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