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