]>
Commit | Line | Data |
---|---|---|
3a473b2a WD |
1 | /* |
2 | * (C) Copyright 2001 | |
3 | * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc. | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | * | |
23 | * modifications for the DB64360 eval board based by Ingo.Assmus@keymile.com | |
24 | */ | |
25 | ||
26 | /* | |
27 | * db64360.c - main board support/init for the Galileo Eval board. | |
28 | */ | |
29 | ||
30 | #include <common.h> | |
31 | #include <74xx_7xx.h> | |
32 | #include "../include/memory.h" | |
33 | #include "../include/pci.h" | |
34 | #include "../include/mv_gen_reg.h" | |
35 | #include <net.h> | |
36 | ||
37 | #include "eth.h" | |
38 | #include "mpsc.h" | |
39 | #include "i2c.h" | |
40 | #include "64360.h" | |
41 | #include "mv_regs.h" | |
42 | ||
43 | #undef DEBUG | |
44 | /*#define DEBUG */ | |
45 | ||
46 | #define MAP_PCI | |
47 | ||
48 | #ifdef DEBUG | |
49 | #define DP(x) x | |
50 | #else | |
51 | #define DP(x) | |
52 | #endif | |
53 | ||
54 | extern void flush_data_cache (void); | |
55 | extern void invalidate_l1_instruction_cache (void); | |
56 | ||
57 | /* ------------------------------------------------------------------------- */ | |
58 | ||
59 | /* this is the current GT register space location */ | |
60 | /* it starts at CFG_DFL_GT_REGS but moves later to CFG_GT_REGS */ | |
61 | ||
62 | /* Unfortunately, we cant change it while we are in flash, so we initialize it | |
63 | * to the "final" value. This means that any debug_led calls before | |
64 | * board_pre_init wont work right (like in cpu_init_f). | |
65 | * See also my_remap_gt_regs below. (NTL) | |
66 | */ | |
67 | ||
68 | void board_prebootm_init (void); | |
69 | unsigned int INTERNAL_REG_BASE_ADDR = CFG_GT_REGS; | |
70 | int display_mem_map (void); | |
71 | ||
72 | /* ------------------------------------------------------------------------- */ | |
73 | ||
74 | /* | |
75 | * This is a version of the GT register space remapping function that | |
76 | * doesn't touch globals (meaning, it's ok to run from flash.) | |
77 | * | |
78 | * Unfortunately, this has the side effect that a writable | |
79 | * INTERNAL_REG_BASE_ADDR is impossible. Oh well. | |
80 | */ | |
81 | ||
82 | void my_remap_gt_regs (u32 cur_loc, u32 new_loc) | |
83 | { | |
84 | u32 temp; | |
85 | ||
86 | /* check and see if it's already moved */ | |
87 | ||
88 | /* original ppcboot 1.1.6 source | |
89 | ||
90 | temp = in_le32((u32 *)(new_loc + INTERNAL_SPACE_DECODE)); | |
91 | if ((temp & 0xffff) == new_loc >> 20) | |
92 | return; | |
93 | ||
94 | temp = (in_le32((u32 *)(cur_loc + INTERNAL_SPACE_DECODE)) & | |
95 | 0xffff0000) | (new_loc >> 20); | |
96 | ||
97 | out_le32((u32 *)(cur_loc + INTERNAL_SPACE_DECODE), temp); | |
98 | ||
99 | while (GTREGREAD(INTERNAL_SPACE_DECODE) != temp); | |
100 | original ppcboot 1.1.6 source end */ | |
101 | ||
102 | temp = in_le32 ((u32 *) (new_loc + INTERNAL_SPACE_DECODE)); | |
103 | if ((temp & 0xffff) == new_loc >> 16) | |
104 | return; | |
105 | ||
106 | temp = (in_le32 ((u32 *) (cur_loc + INTERNAL_SPACE_DECODE)) & | |
107 | 0xffff0000) | (new_loc >> 16); | |
108 | ||
109 | out_le32 ((u32 *) (cur_loc + INTERNAL_SPACE_DECODE), temp); | |
110 | ||
111 | while (GTREGREAD (INTERNAL_SPACE_DECODE) != temp); | |
112 | } | |
113 | ||
114 | #ifdef CONFIG_PCI | |
115 | ||
116 | static void gt_pci_config (void) | |
117 | { | |
118 | unsigned int stat; | |
119 | unsigned int val = 0x00fff864; /* DINK32: BusNum 23:16, DevNum 15:11, FuncNum 10:8, RegNum 7:2 */ | |
120 | ||
121 | /* In PCIX mode devices provide their own bus and device numbers. We query the Discovery II's | |
122 | * config registers by writing ones to the bus and device. | |
123 | * We then update the Virtual register with the correct value for the bus and device. | |
124 | */ | |
125 | if ((GTREGREAD (PCI_0_MODE) & (BIT4 | BIT5)) != 0) { /*if PCI-X */ | |
126 | GT_REG_WRITE (PCI_0_CONFIG_ADDR, BIT31 | val); | |
127 | ||
128 | GT_REG_READ (PCI_0_CONFIG_DATA_VIRTUAL_REG, &stat); | |
129 | ||
130 | GT_REG_WRITE (PCI_0_CONFIG_ADDR, BIT31 | val); | |
131 | GT_REG_WRITE (PCI_0_CONFIG_DATA_VIRTUAL_REG, | |
132 | (stat & 0xffff0000) | CFG_PCI_IDSEL); | |
133 | ||
134 | } | |
135 | if ((GTREGREAD (PCI_1_MODE) & (BIT4 | BIT5)) != 0) { /*if PCI-X */ | |
136 | GT_REG_WRITE (PCI_1_CONFIG_ADDR, BIT31 | val); | |
137 | GT_REG_READ (PCI_1_CONFIG_DATA_VIRTUAL_REG, &stat); | |
138 | ||
139 | GT_REG_WRITE (PCI_1_CONFIG_ADDR, BIT31 | val); | |
140 | GT_REG_WRITE (PCI_1_CONFIG_DATA_VIRTUAL_REG, | |
141 | (stat & 0xffff0000) | CFG_PCI_IDSEL); | |
142 | } | |
143 | ||
144 | /* Enable master */ | |
145 | PCI_MASTER_ENABLE (0, SELF); | |
146 | PCI_MASTER_ENABLE (1, SELF); | |
147 | ||
148 | /* Enable PCI0/1 Mem0 and IO 0 disable all others */ | |
149 | GT_REG_READ (BASE_ADDR_ENABLE, &stat); | |
150 | stat |= (1 << 11) | (1 << 12) | (1 << 13) | (1 << 16) | (1 << 17) | (1 | |
151 | << | |
152 | 18); | |
153 | stat &= ~((1 << 9) | (1 << 10) | (1 << 14) | (1 << 15)); | |
154 | GT_REG_WRITE (BASE_ADDR_ENABLE, stat); | |
155 | ||
156 | /* ronen- add write to pci remap registers for 64460. | |
157 | in 64360 when writing to pci base go and overide remap automaticaly, | |
158 | in 64460 it doesn't */ | |
159 | GT_REG_WRITE (PCI_0_IO_BASE_ADDR, CFG_PCI0_IO_BASE >> 16); | |
160 | GT_REG_WRITE (PCI_0I_O_ADDRESS_REMAP, CFG_PCI0_IO_BASE >> 16); | |
161 | GT_REG_WRITE (PCI_0_IO_SIZE, (CFG_PCI0_IO_SIZE - 1) >> 16); | |
162 | ||
163 | GT_REG_WRITE (PCI_0_MEMORY0_BASE_ADDR, CFG_PCI0_MEM_BASE >> 16); | |
164 | GT_REG_WRITE (PCI_0MEMORY0_ADDRESS_REMAP, CFG_PCI0_MEM_BASE >> 16); | |
165 | GT_REG_WRITE (PCI_0_MEMORY0_SIZE, (CFG_PCI0_MEM_SIZE - 1) >> 16); | |
166 | ||
167 | GT_REG_WRITE (PCI_1_IO_BASE_ADDR, CFG_PCI1_IO_BASE >> 16); | |
168 | GT_REG_WRITE (PCI_1I_O_ADDRESS_REMAP, CFG_PCI1_IO_BASE >> 16); | |
169 | GT_REG_WRITE (PCI_1_IO_SIZE, (CFG_PCI1_IO_SIZE - 1) >> 16); | |
170 | ||
171 | GT_REG_WRITE (PCI_1_MEMORY0_BASE_ADDR, CFG_PCI1_MEM_BASE >> 16); | |
172 | GT_REG_WRITE (PCI_1MEMORY0_ADDRESS_REMAP, CFG_PCI1_MEM_BASE >> 16); | |
173 | GT_REG_WRITE (PCI_1_MEMORY0_SIZE, (CFG_PCI1_MEM_SIZE - 1) >> 16); | |
174 | ||
175 | /* PCI interface settings */ | |
176 | /* Timeout set to retry forever */ | |
177 | GT_REG_WRITE (PCI_0TIMEOUT_RETRY, 0x0); | |
178 | GT_REG_WRITE (PCI_1TIMEOUT_RETRY, 0x0); | |
179 | ||
180 | /* ronen - enable only CS0 and Internal reg!! */ | |
181 | GT_REG_WRITE (PCI_0BASE_ADDRESS_REGISTERS_ENABLE, 0xfffffdfe); | |
182 | GT_REG_WRITE (PCI_1BASE_ADDRESS_REGISTERS_ENABLE, 0xfffffdfe); | |
183 | ||
184 | /*ronen update the pci internal registers base address.*/ | |
185 | #ifdef MAP_PCI | |
186 | for (stat = 0; stat <= PCI_HOST1; stat++) | |
187 | pciWriteConfigReg (stat, | |
188 | PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS, | |
189 | SELF, CFG_GT_REGS); | |
190 | #endif | |
191 | ||
192 | } | |
193 | #endif | |
194 | ||
195 | /* Setup CPU interface paramaters */ | |
196 | static void gt_cpu_config (void) | |
197 | { | |
198 | cpu_t cpu = get_cpu_type (); | |
199 | ulong tmp; | |
200 | ||
201 | /* cpu configuration register */ | |
202 | tmp = GTREGREAD (CPU_CONFIGURATION); | |
203 | ||
204 | /* set the SINGLE_CPU bit see MV64360 P.399 */ | |
205 | #ifndef CFG_GT_DUAL_CPU /* SINGLE_CPU seems to cause JTAG problems */ | |
206 | tmp |= CPU_CONF_SINGLE_CPU; | |
207 | #endif | |
208 | ||
209 | tmp &= ~CPU_CONF_AACK_DELAY_2; | |
210 | ||
211 | tmp |= CPU_CONF_DP_VALID; | |
212 | tmp |= CPU_CONF_AP_VALID; | |
213 | ||
214 | tmp |= CPU_CONF_PIPELINE; | |
215 | ||
216 | GT_REG_WRITE (CPU_CONFIGURATION, tmp); /* Marvell (VXWorks) writes 0x20220FF */ | |
217 | ||
218 | /* CPU master control register */ | |
219 | tmp = GTREGREAD (CPU_MASTER_CONTROL); | |
220 | ||
221 | tmp |= CPU_MAST_CTL_ARB_EN; | |
222 | ||
223 | if ((cpu == CPU_7400) || | |
224 | (cpu == CPU_7410) || (cpu == CPU_7455) || (cpu == CPU_7450)) { | |
225 | ||
226 | tmp |= CPU_MAST_CTL_CLEAN_BLK; | |
227 | tmp |= CPU_MAST_CTL_FLUSH_BLK; | |
228 | ||
229 | } else { | |
230 | /* cleanblock must be cleared for CPUs | |
231 | * that do not support this command (603e, 750) | |
232 | * see Res#1 */ | |
233 | tmp &= ~CPU_MAST_CTL_CLEAN_BLK; | |
234 | tmp &= ~CPU_MAST_CTL_FLUSH_BLK; | |
235 | } | |
236 | GT_REG_WRITE (CPU_MASTER_CONTROL, tmp); | |
237 | } | |
238 | ||
239 | /* | |
240 | * board_pre_init. | |
241 | * | |
242 | * set up gal. device mappings, etc. | |
243 | */ | |
244 | int board_pre_init (void) | |
245 | { | |
246 | uchar sram_boot = 0; | |
247 | ||
248 | /* | |
249 | * set up the GT the way the kernel wants it | |
250 | * the call to move the GT register space will obviously | |
251 | * fail if it has already been done, but we're going to assume | |
252 | * that if it's not at the power-on location, it's where we put | |
253 | * it last time. (huber) | |
254 | */ | |
255 | ||
256 | my_remap_gt_regs (CFG_DFL_GT_REGS, CFG_GT_REGS); | |
257 | ||
258 | /* No PCI in first release of Port To_do: enable it. */ | |
259 | #ifdef CONFIG_PCI | |
260 | gt_pci_config (); | |
261 | #endif | |
262 | /* mask all external interrupt sources */ | |
263 | GT_REG_WRITE (CPU_INTERRUPT_MASK_REGISTER_LOW, 0); | |
264 | GT_REG_WRITE (CPU_INTERRUPT_MASK_REGISTER_HIGH, 0); | |
265 | /* new in MV6436x */ | |
266 | GT_REG_WRITE (CPU_INTERRUPT_1_MASK_REGISTER_LOW, 0); | |
267 | GT_REG_WRITE (CPU_INTERRUPT_1_MASK_REGISTER_HIGH, 0); | |
268 | /* --------------------- */ | |
269 | GT_REG_WRITE (PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0); | |
270 | GT_REG_WRITE (PCI_0INTERRUPT_CAUSE_MASK_REGISTER_HIGH, 0); | |
271 | GT_REG_WRITE (PCI_1INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0); | |
272 | GT_REG_WRITE (PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH, 0); | |
273 | /* does not exist in MV6436x | |
274 | GT_REG_WRITE(CPU_INT_0_MASK, 0); | |
275 | GT_REG_WRITE(CPU_INT_1_MASK, 0); | |
276 | GT_REG_WRITE(CPU_INT_2_MASK, 0); | |
277 | GT_REG_WRITE(CPU_INT_3_MASK, 0); | |
278 | --------------------- */ | |
279 | ||
280 | ||
281 | /* ----- DEVICE BUS SETTINGS ------ */ | |
282 | ||
283 | /* | |
284 | * EVB | |
285 | * 0 - SRAM ???? | |
286 | * 1 - RTC ???? | |
287 | * 2 - UART ???? | |
288 | * 3 - Flash checked 32Bit Intel Strata | |
289 | * boot - BootCS checked 8Bit 29LV040B | |
290 | * | |
291 | * Zuma | |
292 | * 0 - Flash | |
293 | * boot - BootCS | |
294 | */ | |
295 | ||
296 | /* | |
297 | * the dual 7450 module requires burst access to the boot | |
298 | * device, so the serial rom copies the boot device to the | |
299 | * on-board sram on the eval board, and updates the correct | |
300 | * registers to boot from the sram. (device0) | |
301 | */ | |
302 | if (memoryGetDeviceBaseAddress (DEVICE0) == CFG_DFL_BOOTCS_BASE) | |
303 | sram_boot = 1; | |
304 | if (!sram_boot) | |
305 | memoryMapDeviceSpace (DEVICE0, CFG_DEV0_SPACE, CFG_DEV0_SIZE); | |
306 | ||
307 | memoryMapDeviceSpace (DEVICE1, CFG_DEV1_SPACE, CFG_DEV1_SIZE); | |
308 | memoryMapDeviceSpace (DEVICE2, CFG_DEV2_SPACE, CFG_DEV2_SIZE); | |
309 | memoryMapDeviceSpace (DEVICE3, CFG_DEV3_SPACE, CFG_DEV3_SIZE); | |
310 | ||
311 | ||
312 | /* configure device timing */ | |
313 | #ifdef CFG_DEV0_PAR /* set port parameters for SRAM device module access */ | |
314 | if (!sram_boot) | |
315 | GT_REG_WRITE (DEVICE_BANK0PARAMETERS, CFG_DEV0_PAR); | |
316 | #endif | |
317 | ||
318 | #ifdef CFG_DEV1_PAR /* set port parameters for RTC device module access */ | |
319 | GT_REG_WRITE (DEVICE_BANK1PARAMETERS, CFG_DEV1_PAR); | |
320 | #endif | |
321 | #ifdef CFG_DEV2_PAR /* set port parameters for DUART device module access */ | |
322 | GT_REG_WRITE (DEVICE_BANK2PARAMETERS, CFG_DEV2_PAR); | |
323 | #endif | |
324 | ||
325 | #ifdef CFG_32BIT_BOOT_PAR /* set port parameters for Flash device module access */ | |
326 | /* detect if we are booting from the 32 bit flash */ | |
327 | if (GTREGREAD (DEVICE_BOOT_BANK_PARAMETERS) & (0x3 << 20)) { | |
328 | /* 32 bit boot flash */ | |
329 | GT_REG_WRITE (DEVICE_BANK3PARAMETERS, CFG_8BIT_BOOT_PAR); | |
330 | GT_REG_WRITE (DEVICE_BOOT_BANK_PARAMETERS, | |
331 | CFG_32BIT_BOOT_PAR); | |
332 | } else { | |
333 | /* 8 bit boot flash */ | |
334 | GT_REG_WRITE (DEVICE_BANK3PARAMETERS, CFG_32BIT_BOOT_PAR); | |
335 | GT_REG_WRITE (DEVICE_BOOT_BANK_PARAMETERS, CFG_8BIT_BOOT_PAR); | |
336 | } | |
337 | #else | |
338 | /* 8 bit boot flash only */ | |
339 | /* GT_REG_WRITE(DEVICE_BOOT_BANK_PARAMETERS, CFG_8BIT_BOOT_PAR);*/ | |
340 | #endif | |
341 | ||
342 | ||
343 | gt_cpu_config (); | |
344 | ||
345 | /* MPP setup */ | |
346 | GT_REG_WRITE (MPP_CONTROL0, CFG_MPP_CONTROL_0); | |
347 | GT_REG_WRITE (MPP_CONTROL1, CFG_MPP_CONTROL_1); | |
348 | GT_REG_WRITE (MPP_CONTROL2, CFG_MPP_CONTROL_2); | |
349 | GT_REG_WRITE (MPP_CONTROL3, CFG_MPP_CONTROL_3); | |
350 | ||
351 | GT_REG_WRITE (GPP_LEVEL_CONTROL, CFG_GPP_LEVEL_CONTROL); | |
352 | DEBUG_LED0_ON (); | |
353 | DEBUG_LED1_ON (); | |
354 | DEBUG_LED2_ON (); | |
355 | ||
356 | return 0; | |
357 | } | |
358 | ||
359 | /* various things to do after relocation */ | |
360 | ||
361 | int misc_init_r () | |
362 | { | |
363 | icache_enable (); | |
364 | #ifdef CFG_L2 | |
365 | l2cache_enable (); | |
366 | #endif | |
367 | #ifdef CONFIG_MPSC | |
368 | ||
369 | mpsc_sdma_init (); | |
370 | mpsc_init2 (); | |
371 | #endif | |
372 | ||
373 | #if 0 | |
374 | /* disable the dcache and MMU */ | |
375 | dcache_lock (); | |
376 | #endif | |
377 | return 0; | |
378 | } | |
379 | ||
380 | void after_reloc (ulong dest_addr, gd_t * gd) | |
381 | { | |
382 | /* check to see if we booted from the sram. If so, move things | |
383 | * back to the way they should be. (we're running from main | |
384 | * memory at this point now */ | |
385 | if (memoryGetDeviceBaseAddress (DEVICE0) == CFG_DFL_BOOTCS_BASE) { | |
386 | memoryMapDeviceSpace (DEVICE0, CFG_DEV0_SPACE, CFG_DEV0_SIZE); | |
387 | memoryMapDeviceSpace (BOOT_DEVICE, CFG_DFL_BOOTCS_BASE, _8M); | |
388 | } | |
389 | display_mem_map (); | |
390 | /* now, jump to the main ppcboot board init code */ | |
391 | board_init_r (gd, dest_addr); | |
392 | /* NOTREACHED */ | |
393 | } | |
394 | ||
395 | /* ------------------------------------------------------------------------- */ | |
396 | ||
397 | /* | |
398 | * Check Board Identity: | |
399 | * | |
400 | * right now, assume borad type. (there is just one...after all) | |
401 | */ | |
402 | ||
403 | int checkboard (void) | |
404 | { | |
405 | int l_type = 0; | |
406 | ||
407 | printf ("BOARD: %s\n", CFG_BOARD_NAME); | |
408 | return (l_type); | |
409 | } | |
410 | ||
411 | /* utility functions */ | |
412 | void debug_led (int led, int mode) | |
413 | { | |
414 | volatile int *addr = 0; | |
415 | int dummy; | |
416 | ||
417 | if (mode == 1) { | |
418 | switch (led) { | |
419 | case 0: | |
420 | addr = (int *) ((unsigned int) CFG_DEV1_SPACE | | |
421 | 0x08000); | |
422 | break; | |
423 | ||
424 | case 1: | |
425 | addr = (int *) ((unsigned int) CFG_DEV1_SPACE | | |
426 | 0x0c000); | |
427 | break; | |
428 | ||
429 | case 2: | |
430 | addr = (int *) ((unsigned int) CFG_DEV1_SPACE | | |
431 | 0x10000); | |
432 | break; | |
433 | } | |
434 | } else if (mode == 0) { | |
435 | switch (led) { | |
436 | case 0: | |
437 | addr = (int *) ((unsigned int) CFG_DEV1_SPACE | | |
438 | 0x14000); | |
439 | break; | |
440 | ||
441 | case 1: | |
442 | addr = (int *) ((unsigned int) CFG_DEV1_SPACE | | |
443 | 0x18000); | |
444 | break; | |
445 | ||
446 | case 2: | |
447 | addr = (int *) ((unsigned int) CFG_DEV1_SPACE | | |
448 | 0x1c000); | |
449 | break; | |
450 | } | |
451 | } | |
452 | ||
453 | dummy = *addr; | |
454 | } | |
455 | ||
456 | int display_mem_map (void) | |
457 | { | |
458 | int i, j; | |
459 | unsigned int base, size, width; | |
460 | ||
461 | /* SDRAM */ | |
462 | printf ("SD (DDR) RAM\n"); | |
463 | for (i = 0; i <= BANK3; i++) { | |
464 | base = memoryGetBankBaseAddress (i); | |
465 | size = memoryGetBankSize (i); | |
466 | if (size != 0) { | |
467 | printf ("BANK%d: base - 0x%08x\tsize - %dM bytes\n", | |
468 | i, base, size >> 20); | |
469 | } | |
470 | } | |
471 | ||
472 | /* CPU's PCI windows */ | |
473 | for (i = 0; i <= PCI_HOST1; i++) { | |
474 | printf ("\nCPU's PCI %d windows\n", i); | |
475 | base = pciGetSpaceBase (i, PCI_IO); | |
476 | size = pciGetSpaceSize (i, PCI_IO); | |
477 | printf (" IO: base - 0x%08x\tsize - %dM bytes\n", base, | |
478 | size >> 20); | |
479 | for (j = 0; | |
480 | j <= | |
481 | PCI_REGION0 | |
482 | /*ronen currently only first PCI MEM is used 3 */ ; | |
483 | j++) { | |
484 | base = pciGetSpaceBase (i, j); | |
485 | size = pciGetSpaceSize (i, j); | |
486 | printf ("MEMORY %d: base - 0x%08x\tsize - %dM bytes\n", j, base, size >> 20); | |
487 | } | |
488 | } | |
489 | ||
490 | /* Devices */ | |
491 | printf ("\nDEVICES\n"); | |
492 | for (i = 0; i <= DEVICE3; i++) { | |
493 | base = memoryGetDeviceBaseAddress (i); | |
494 | size = memoryGetDeviceSize (i); | |
495 | width = memoryGetDeviceWidth (i) * 8; | |
496 | printf ("DEV %d: base - 0x%08x size - %dM bytes\twidth - %d bits", i, base, size >> 20, width); | |
497 | if (i == 0) | |
498 | printf ("\t- EXT SRAM (actual - 1M)\n"); | |
499 | else if (i == 1) | |
500 | printf ("\t- RTC\n"); | |
501 | else if (i == 2) | |
502 | printf ("\t- UART\n"); | |
503 | else | |
504 | printf ("\t- LARGE FLASH\n"); | |
505 | } | |
506 | ||
507 | /* Bootrom */ | |
508 | base = memoryGetDeviceBaseAddress (BOOT_DEVICE); /* Boot */ | |
509 | size = memoryGetDeviceSize (BOOT_DEVICE); | |
510 | width = memoryGetDeviceWidth (BOOT_DEVICE) * 8; | |
511 | printf (" BOOT: base - 0x%08x size - %dM bytes\twidth - %d bits\n", | |
512 | base, size >> 20, width); | |
513 | return (0); | |
514 | } | |
515 | ||
516 | /* DRAM check routines copied from gw8260 */ | |
517 | ||
518 | #if defined (CFG_DRAM_TEST) | |
519 | ||
520 | /*********************************************************************/ | |
521 | /* NAME: move64() - moves a double word (64-bit) */ | |
522 | /* */ | |
523 | /* DESCRIPTION: */ | |
524 | /* this function performs a double word move from the data at */ | |
525 | /* the source pointer to the location at the destination pointer. */ | |
526 | /* */ | |
527 | /* INPUTS: */ | |
528 | /* unsigned long long *src - pointer to data to move */ | |
529 | /* */ | |
530 | /* OUTPUTS: */ | |
531 | /* unsigned long long *dest - pointer to locate to move data */ | |
532 | /* */ | |
533 | /* RETURNS: */ | |
534 | /* None */ | |
535 | /* */ | |
536 | /* RESTRICTIONS/LIMITATIONS: */ | |
537 | /* May cloober fr0. */ | |
538 | /* */ | |
539 | /*********************************************************************/ | |
540 | static void move64 (unsigned long long *src, unsigned long long *dest) | |
541 | { | |
542 | asm ("lfd 0, 0(3)\n\t" /* fpr0 = *scr */ | |
543 | "stfd 0, 0(4)" /* *dest = fpr0 */ | |
544 | : : : "fr0"); /* Clobbers fr0 */ | |
545 | return; | |
546 | } | |
547 | ||
548 | ||
549 | #if defined (CFG_DRAM_TEST_DATA) | |
550 | ||
551 | unsigned long long pattern[] = { | |
552 | 0xaaaaaaaaaaaaaaaa, | |
553 | 0xcccccccccccccccc, | |
554 | 0xf0f0f0f0f0f0f0f0, | |
555 | 0xff00ff00ff00ff00, | |
556 | 0xffff0000ffff0000, | |
557 | 0xffffffff00000000, | |
558 | 0x00000000ffffffff, | |
559 | 0x0000ffff0000ffff, | |
560 | 0x00ff00ff00ff00ff, | |
561 | 0x0f0f0f0f0f0f0f0f, | |
562 | 0x3333333333333333, | |
563 | 0x5555555555555555 | |
564 | }; | |
565 | ||
566 | /*********************************************************************/ | |
567 | /* NAME: mem_test_data() - test data lines for shorts and opens */ | |
568 | /* */ | |
569 | /* DESCRIPTION: */ | |
570 | /* Tests data lines for shorts and opens by forcing adjacent data */ | |
571 | /* to opposite states. Because the data lines could be routed in */ | |
572 | /* an arbitrary manner the must ensure test patterns ensure that */ | |
573 | /* every case is tested. By using the following series of binary */ | |
574 | /* patterns every combination of adjacent bits is test regardless */ | |
575 | /* of routing. */ | |
576 | /* */ | |
577 | /* ...101010101010101010101010 */ | |
578 | /* ...110011001100110011001100 */ | |
579 | /* ...111100001111000011110000 */ | |
580 | /* ...111111110000000011111111 */ | |
581 | /* */ | |
582 | /* Carrying this out, gives us six hex patterns as follows: */ | |
583 | /* */ | |
584 | /* 0xaaaaaaaaaaaaaaaa */ | |
585 | /* 0xcccccccccccccccc */ | |
586 | /* 0xf0f0f0f0f0f0f0f0 */ | |
587 | /* 0xff00ff00ff00ff00 */ | |
588 | /* 0xffff0000ffff0000 */ | |
589 | /* 0xffffffff00000000 */ | |
590 | /* */ | |
591 | /* The number test patterns will always be given by: */ | |
592 | /* */ | |
593 | /* log(base 2)(number data bits) = log2 (64) = 6 */ | |
594 | /* */ | |
595 | /* To test for short and opens to other signals on our boards. we */ | |
596 | /* simply */ | |
597 | /* test with the 1's complemnt of the paterns as well. */ | |
598 | /* */ | |
599 | /* OUTPUTS: */ | |
600 | /* Displays failing test pattern */ | |
601 | /* */ | |
602 | /* RETURNS: */ | |
603 | /* 0 - Passed test */ | |
604 | /* 1 - Failed test */ | |
605 | /* */ | |
606 | /* RESTRICTIONS/LIMITATIONS: */ | |
607 | /* Assumes only one one SDRAM bank */ | |
608 | /* */ | |
609 | /*********************************************************************/ | |
610 | int mem_test_data (void) | |
611 | { | |
612 | unsigned long long *pmem = (unsigned long long *) CFG_MEMTEST_START; | |
613 | unsigned long long temp64; | |
614 | int num_patterns = sizeof (pattern) / sizeof (pattern[0]); | |
615 | int i; | |
616 | unsigned int hi, lo; | |
617 | ||
618 | for (i = 0; i < num_patterns; i++) { | |
619 | move64 (&(pattern[i]), pmem); | |
620 | move64 (pmem, &temp64); | |
621 | ||
622 | /* hi = (temp64>>32) & 0xffffffff; */ | |
623 | /* lo = temp64 & 0xffffffff; */ | |
624 | /* printf("\ntemp64 = 0x%08x%08x", hi, lo); */ | |
625 | ||
626 | hi = (pattern[i] >> 32) & 0xffffffff; | |
627 | lo = pattern[i] & 0xffffffff; | |
628 | /* printf("\npattern[%d] = 0x%08x%08x", i, hi, lo); */ | |
629 | ||
630 | if (temp64 != pattern[i]) { | |
631 | printf ("\n Data Test Failed, pattern 0x%08x%08x", | |
632 | hi, lo); | |
633 | return 1; | |
634 | } | |
635 | } | |
636 | ||
637 | return 0; | |
638 | } | |
639 | #endif /* CFG_DRAM_TEST_DATA */ | |
640 | ||
641 | #if defined (CFG_DRAM_TEST_ADDRESS) | |
642 | /*********************************************************************/ | |
643 | /* NAME: mem_test_address() - test address lines */ | |
644 | /* */ | |
645 | /* DESCRIPTION: */ | |
646 | /* This function performs a test to verify that each word im */ | |
647 | /* memory is uniquly addressable. The test sequence is as follows: */ | |
648 | /* */ | |
649 | /* 1) write the address of each word to each word. */ | |
650 | /* 2) verify that each location equals its address */ | |
651 | /* */ | |
652 | /* OUTPUTS: */ | |
653 | /* Displays failing test pattern and address */ | |
654 | /* */ | |
655 | /* RETURNS: */ | |
656 | /* 0 - Passed test */ | |
657 | /* 1 - Failed test */ | |
658 | /* */ | |
659 | /* RESTRICTIONS/LIMITATIONS: */ | |
660 | /* */ | |
661 | /* */ | |
662 | /*********************************************************************/ | |
663 | int mem_test_address (void) | |
664 | { | |
665 | volatile unsigned int *pmem = | |
666 | (volatile unsigned int *) CFG_MEMTEST_START; | |
667 | const unsigned int size = (CFG_MEMTEST_END - CFG_MEMTEST_START) / 4; | |
668 | unsigned int i; | |
669 | ||
670 | /* write address to each location */ | |
671 | for (i = 0; i < size; i++) { | |
672 | pmem[i] = i; | |
673 | } | |
674 | ||
675 | /* verify each loaction */ | |
676 | for (i = 0; i < size; i++) { | |
677 | if (pmem[i] != i) { | |
678 | printf ("\n Address Test Failed at 0x%x", i); | |
679 | return 1; | |
680 | } | |
681 | } | |
682 | return 0; | |
683 | } | |
684 | #endif /* CFG_DRAM_TEST_ADDRESS */ | |
685 | ||
686 | #if defined (CFG_DRAM_TEST_WALK) | |
687 | /*********************************************************************/ | |
688 | /* NAME: mem_march() - memory march */ | |
689 | /* */ | |
690 | /* DESCRIPTION: */ | |
691 | /* Marches up through memory. At each location verifies rmask if */ | |
692 | /* read = 1. At each location write wmask if write = 1. Displays */ | |
693 | /* failing address and pattern. */ | |
694 | /* */ | |
695 | /* INPUTS: */ | |
696 | /* volatile unsigned long long * base - start address of test */ | |
697 | /* unsigned int size - number of dwords(64-bit) to test */ | |
698 | /* unsigned long long rmask - read verify mask */ | |
699 | /* unsigned long long wmask - wrtie verify mask */ | |
700 | /* short read - verifies rmask if read = 1 */ | |
701 | /* short write - writes wmask if write = 1 */ | |
702 | /* */ | |
703 | /* OUTPUTS: */ | |
704 | /* Displays failing test pattern and address */ | |
705 | /* */ | |
706 | /* RETURNS: */ | |
707 | /* 0 - Passed test */ | |
708 | /* 1 - Failed test */ | |
709 | /* */ | |
710 | /* RESTRICTIONS/LIMITATIONS: */ | |
711 | /* */ | |
712 | /* */ | |
713 | /*********************************************************************/ | |
714 | int mem_march (volatile unsigned long long *base, | |
715 | unsigned int size, | |
716 | unsigned long long rmask, | |
717 | unsigned long long wmask, short read, short write) | |
718 | { | |
719 | unsigned int i; | |
720 | unsigned long long temp; | |
721 | unsigned int hitemp, lotemp, himask, lomask; | |
722 | ||
723 | for (i = 0; i < size; i++) { | |
724 | if (read != 0) { | |
725 | /* temp = base[i]; */ | |
726 | move64 ((unsigned long long *) &(base[i]), &temp); | |
727 | if (rmask != temp) { | |
728 | hitemp = (temp >> 32) & 0xffffffff; | |
729 | lotemp = temp & 0xffffffff; | |
730 | himask = (rmask >> 32) & 0xffffffff; | |
731 | lomask = rmask & 0xffffffff; | |
732 | ||
733 | printf ("\n Walking one's test failed: address = 0x%08x," "\n\texpected 0x%08x%08x, found 0x%08x%08x", i << 3, himask, lomask, hitemp, lotemp); | |
734 | return 1; | |
735 | } | |
736 | } | |
737 | if (write != 0) { | |
738 | /* base[i] = wmask; */ | |
739 | move64 (&wmask, (unsigned long long *) &(base[i])); | |
740 | } | |
741 | } | |
742 | return 0; | |
743 | } | |
744 | #endif /* CFG_DRAM_TEST_WALK */ | |
745 | ||
746 | /*********************************************************************/ | |
747 | /* NAME: mem_test_walk() - a simple walking ones test */ | |
748 | /* */ | |
749 | /* DESCRIPTION: */ | |
750 | /* Performs a walking ones through entire physical memory. The */ | |
751 | /* test uses as series of memory marches, mem_march(), to verify */ | |
752 | /* and write the test patterns to memory. The test sequence is as */ | |
753 | /* follows: */ | |
754 | /* 1) march writing 0000...0001 */ | |
755 | /* 2) march verifying 0000...0001 , writing 0000...0010 */ | |
756 | /* 3) repeat step 2 shifting masks left 1 bit each time unitl */ | |
757 | /* the write mask equals 1000...0000 */ | |
758 | /* 4) march verifying 1000...0000 */ | |
759 | /* The test fails if any of the memory marches return a failure. */ | |
760 | /* */ | |
761 | /* OUTPUTS: */ | |
762 | /* Displays which pass on the memory test is executing */ | |
763 | /* */ | |
764 | /* RETURNS: */ | |
765 | /* 0 - Passed test */ | |
766 | /* 1 - Failed test */ | |
767 | /* */ | |
768 | /* RESTRICTIONS/LIMITATIONS: */ | |
769 | /* */ | |
770 | /* */ | |
771 | /*********************************************************************/ | |
772 | int mem_test_walk (void) | |
773 | { | |
774 | unsigned long long mask; | |
775 | volatile unsigned long long *pmem = | |
776 | (volatile unsigned long long *) CFG_MEMTEST_START; | |
777 | const unsigned long size = (CFG_MEMTEST_END - CFG_MEMTEST_START) / 8; | |
778 | ||
779 | unsigned int i; | |
780 | ||
781 | mask = 0x01; | |
782 | ||
783 | printf ("Initial Pass"); | |
784 | mem_march (pmem, size, 0x0, 0x1, 0, 1); | |
785 | ||
786 | printf ("\b\b\b\b\b\b\b\b\b\b\b\b"); | |
787 | printf (" "); | |
788 | printf (" "); | |
789 | printf ("\b\b\b\b\b\b\b\b\b\b\b\b"); | |
790 | ||
791 | for (i = 0; i < 63; i++) { | |
792 | printf ("Pass %2d", i + 2); | |
793 | if (mem_march (pmem, size, mask, mask << 1, 1, 1) != 0) { | |
794 | /*printf("mask: 0x%x, pass: %d, ", mask, i); */ | |
795 | return 1; | |
796 | } | |
797 | mask = mask << 1; | |
798 | printf ("\b\b\b\b\b\b\b"); | |
799 | } | |
800 | ||
801 | printf ("Last Pass"); | |
802 | if (mem_march (pmem, size, 0, mask, 0, 1) != 0) { | |
803 | /* printf("mask: 0x%x", mask); */ | |
804 | return 1; | |
805 | } | |
806 | printf ("\b\b\b\b\b\b\b\b\b"); | |
807 | printf (" "); | |
808 | printf ("\b\b\b\b\b\b\b\b\b"); | |
809 | ||
810 | return 0; | |
811 | } | |
812 | ||
813 | /*********************************************************************/ | |
814 | /* NAME: testdram() - calls any enabled memory tests */ | |
815 | /* */ | |
816 | /* DESCRIPTION: */ | |
817 | /* Runs memory tests if the environment test variables are set to */ | |
818 | /* 'y'. */ | |
819 | /* */ | |
820 | /* INPUTS: */ | |
821 | /* testdramdata - If set to 'y', data test is run. */ | |
822 | /* testdramaddress - If set to 'y', address test is run. */ | |
823 | /* testdramwalk - If set to 'y', walking ones test is run */ | |
824 | /* */ | |
825 | /* OUTPUTS: */ | |
826 | /* None */ | |
827 | /* */ | |
828 | /* RETURNS: */ | |
829 | /* 0 - Passed test */ | |
830 | /* 1 - Failed test */ | |
831 | /* */ | |
832 | /* RESTRICTIONS/LIMITATIONS: */ | |
833 | /* */ | |
834 | /* */ | |
835 | /*********************************************************************/ | |
836 | int testdram (void) | |
837 | { | |
838 | char *s; | |
839 | int rundata, runaddress, runwalk; | |
840 | ||
841 | s = getenv ("testdramdata"); | |
842 | rundata = (s && (*s == 'y')) ? 1 : 0; | |
843 | s = getenv ("testdramaddress"); | |
844 | runaddress = (s && (*s == 'y')) ? 1 : 0; | |
845 | s = getenv ("testdramwalk"); | |
846 | runwalk = (s && (*s == 'y')) ? 1 : 0; | |
847 | ||
848 | /* rundata = 1; */ | |
849 | /* runaddress = 0; */ | |
850 | /* runwalk = 0; */ | |
851 | ||
852 | if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) { | |
853 | printf ("Testing RAM from 0x%08x to 0x%08x ... (don't panic... that will take a moment !!!!)\n", CFG_MEMTEST_START, CFG_MEMTEST_END); | |
854 | } | |
855 | #ifdef CFG_DRAM_TEST_DATA | |
856 | if (rundata == 1) { | |
857 | printf ("Test DATA ... "); | |
858 | if (mem_test_data () == 1) { | |
859 | printf ("failed \n"); | |
860 | return 1; | |
861 | } else | |
862 | printf ("ok \n"); | |
863 | } | |
864 | #endif | |
865 | #ifdef CFG_DRAM_TEST_ADDRESS | |
866 | if (runaddress == 1) { | |
867 | printf ("Test ADDRESS ... "); | |
868 | if (mem_test_address () == 1) { | |
869 | printf ("failed \n"); | |
870 | return 1; | |
871 | } else | |
872 | printf ("ok \n"); | |
873 | } | |
874 | #endif | |
875 | #ifdef CFG_DRAM_TEST_WALK | |
876 | if (runwalk == 1) { | |
877 | printf ("Test WALKING ONEs ... "); | |
878 | if (mem_test_walk () == 1) { | |
879 | printf ("failed \n"); | |
880 | return 1; | |
881 | } else | |
882 | printf ("ok \n"); | |
883 | } | |
884 | #endif | |
885 | if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) { | |
886 | printf ("passed\n"); | |
887 | } | |
888 | return 0; | |
889 | ||
890 | } | |
891 | #endif /* CFG_DRAM_TEST */ | |
892 | ||
893 | /* ronen - the below functions are used by the bootm function */ | |
894 | /* - we map the base register to fbe00000 (same mapping as in the LSP) */ | |
895 | /* - we turn off the RX gig dmas - to prevent the dma from overunning */ | |
896 | /* the kernel data areas. */ | |
897 | /* - we diable and invalidate the icache and dcache. */ | |
898 | void my_remap_gt_regs_bootm (u32 cur_loc, u32 new_loc) | |
899 | { | |
900 | u32 temp; | |
901 | ||
902 | temp = in_le32 ((u32 *) (new_loc + INTERNAL_SPACE_DECODE)); | |
903 | if ((temp & 0xffff) == new_loc >> 16) | |
904 | return; | |
905 | ||
906 | temp = (in_le32 ((u32 *) (cur_loc + INTERNAL_SPACE_DECODE)) & | |
907 | 0xffff0000) | (new_loc >> 16); | |
908 | ||
909 | out_le32 ((u32 *) (cur_loc + INTERNAL_SPACE_DECODE), temp); | |
910 | ||
911 | while ((WORD_SWAP (*((volatile unsigned int *) (NONE_CACHEABLE | | |
912 | new_loc | | |
913 | (INTERNAL_SPACE_DECODE))))) | |
914 | != temp); | |
915 | ||
916 | } | |
917 | ||
918 | void board_prebootm_init () | |
919 | { | |
920 | ||
921 | /* change window size of PCI1 IO in order tp prevent overlaping with REG BASE. */ | |
922 | GT_REG_WRITE (PCI_1_IO_SIZE, (_64K - 1) >> 16); | |
923 | ||
924 | /* Stop GigE Rx DMA engines */ | |
925 | GT_REG_WRITE (MV64360_ETH_RECEIVE_QUEUE_COMMAND_REG (0), 0x0000ff00); | |
926 | GT_REG_WRITE (MV64360_ETH_RECEIVE_QUEUE_COMMAND_REG (1), 0x0000ff00); | |
927 | /* MV_REG_WRITE (MV64360_ETH_RECEIVE_QUEUE_COMMAND_REG(2), 0x0000ff00); */ | |
928 | ||
929 | /* Relocate MV64360 internal regs */ | |
930 | my_remap_gt_regs_bootm (CFG_GT_REGS, BRIDGE_REG_BASE_BOOTM); | |
931 | ||
932 | icache_disable (); | |
933 | invalidate_l1_instruction_cache (); | |
934 | flush_data_cache (); | |
935 | dcache_disable (); | |
936 | } |