]>
Commit | Line | Data |
---|---|---|
b79316f2 SR |
1 | /* |
2 | * Copyright (C) 2005 Sandburst Corporation | |
3 | * | |
4 | * See file CREDITS for list of people who contributed to this | |
5 | * project. | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License as | |
9 | * published by the Free Software Foundation; either version 2 of | |
10 | * the License, or (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
20 | * MA 02111-1307 USA | |
21 | */ | |
22 | #include <config.h> | |
23 | #include <common.h> | |
24 | #include <command.h> | |
25 | #include <asm/processor.h> | |
26 | #include <asm/io.h> | |
27 | #include <spd_sdram.h> | |
28 | #include <i2c.h> | |
29 | #include "ppc440gx_i2c.h" | |
30 | #include "sb_common.h" | |
31 | ||
d87080b7 WD |
32 | DECLARE_GLOBAL_DATA_PTR; |
33 | ||
b79316f2 SR |
34 | long int fixed_sdram (void); |
35 | ||
36 | /************************************************************************* | |
37 | * metrobox_get_master | |
38 | * | |
3d078ce6 | 39 | * PRI_N - active low signal. If the GPIO pin is low we are the master |
b79316f2 SR |
40 | * |
41 | ************************************************************************/ | |
42 | int sbcommon_get_master(void) | |
43 | { | |
44 | ppc440_gpio_regs_t *gpio_regs; | |
45 | ||
6d0f6bcf | 46 | gpio_regs = (ppc440_gpio_regs_t *)CONFIG_SYS_GPIO_BASE; |
b79316f2 SR |
47 | |
48 | if (gpio_regs->in & SBCOMMON_GPIO_PRI_N) { | |
49 | return 0; | |
50 | } | |
51 | else { | |
52 | return 1; | |
53 | } | |
54 | } | |
55 | ||
56 | /************************************************************************* | |
57 | * metrobox_secondary_present | |
58 | * | |
59 | * Figure out if secondary/slave board is present | |
60 | * | |
61 | ************************************************************************/ | |
62 | int sbcommon_secondary_present(void) | |
63 | { | |
64 | ppc440_gpio_regs_t *gpio_regs; | |
65 | ||
6d0f6bcf | 66 | gpio_regs = (ppc440_gpio_regs_t *)CONFIG_SYS_GPIO_BASE; |
b79316f2 SR |
67 | |
68 | if (gpio_regs->in & SBCOMMON_GPIO_SEC_PRES) | |
69 | return 0; | |
70 | else | |
71 | return 1; | |
72 | } | |
73 | ||
74 | /************************************************************************* | |
75 | * sbcommon_get_serial_number | |
76 | * | |
77 | * Retrieve the board serial number via the mac address in eeprom | |
78 | * | |
79 | ************************************************************************/ | |
80 | unsigned short sbcommon_get_serial_number(void) | |
81 | { | |
82 | unsigned char buff[0x100]; | |
83 | unsigned short sernum; | |
84 | ||
85 | /* Get the board serial number from eeprom */ | |
3d078ce6 | 86 | /* Initialize I2C */ |
6d0f6bcf | 87 | i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); |
b79316f2 SR |
88 | |
89 | /* Read 256 bytes in EEPROM */ | |
90 | i2c_read (0x50, 0, 1, buff, 0x100); | |
91 | ||
92 | memcpy(&sernum, &buff[0xF4], 2); | |
93 | sernum /= 32; | |
94 | ||
95 | return (sernum); | |
96 | } | |
97 | ||
98 | /************************************************************************* | |
99 | * sbcommon_fans | |
100 | * | |
3d078ce6 | 101 | * Spin up fans 2 & 3 to get some air moving. OS will take care |
b79316f2 SR |
102 | * of the rest. This is mostly a precaution... |
103 | * | |
104 | * Assumes i2c bus 1 is ready. | |
105 | * | |
106 | ************************************************************************/ | |
107 | void sbcommon_fans(void) | |
108 | { | |
109 | /* | |
110 | * Attempt to turn on 2 of the fans... | |
111 | * Need to go through the bridge | |
112 | */ | |
113 | puts ("FANS: "); | |
114 | ||
115 | /* select fan4 through the bridge */ | |
116 | i2c_reg_write1(0x73, /* addr */ | |
117 | 0x00, /* reg */ | |
118 | 0x08); /* val = bus 4 */ | |
119 | ||
120 | /* Turn on FAN 4 */ | |
121 | i2c_reg_write1(0x2e, | |
122 | 1, | |
123 | 0x80); | |
124 | ||
125 | i2c_reg_write1(0x2e, | |
126 | 0, | |
127 | 0x19); | |
128 | ||
129 | /* Deselect bus 4 on the bridge */ | |
130 | i2c_reg_write1(0x73, | |
131 | 0x00, | |
132 | 0x00); | |
133 | ||
134 | /* select fan3 through the bridge */ | |
135 | i2c_reg_write1(0x73, /* addr */ | |
136 | 0x00, /* reg */ | |
137 | 0x04); /* val = bus 3 */ | |
138 | ||
139 | /* Turn on FAN 3 */ | |
140 | i2c_reg_write1(0x2e, | |
141 | 1, | |
142 | 0x80); | |
143 | ||
144 | i2c_reg_write1(0x2e, | |
145 | 0, | |
146 | 0x19); | |
147 | ||
148 | /* Deselect bus 3 on the bridge */ | |
149 | i2c_reg_write1(0x73, | |
150 | 0x00, | |
151 | 0x00); | |
152 | ||
153 | /* select fan2 through the bridge */ | |
154 | i2c_reg_write1(0x73, /* addr */ | |
155 | 0x00, /* reg */ | |
156 | 0x02); /* val = bus 4 */ | |
157 | ||
158 | /* Turn on FAN 2 */ | |
159 | i2c_reg_write1(0x2e, | |
160 | 1, | |
161 | 0x80); | |
162 | ||
163 | i2c_reg_write1(0x2e, | |
164 | 0, | |
165 | 0x19); | |
166 | ||
167 | /* Deselect bus 2 on the bridge */ | |
168 | i2c_reg_write1(0x73, | |
169 | 0x00, | |
170 | 0x00); | |
171 | ||
172 | /* select fan1 through the bridge */ | |
173 | i2c_reg_write1(0x73, /* addr */ | |
174 | 0x00, /* reg */ | |
175 | 0x01); /* val = bus 0 */ | |
176 | ||
177 | /* Turn on FAN 1 */ | |
178 | i2c_reg_write1(0x2e, | |
179 | 1, | |
180 | 0x80); | |
181 | ||
182 | i2c_reg_write1(0x2e, | |
183 | 0, | |
184 | 0x19); | |
185 | ||
186 | /* Deselect bus 1 on the bridge */ | |
187 | i2c_reg_write1(0x73, | |
188 | 0x00, | |
189 | 0x00); | |
190 | ||
191 | puts ("on\n"); | |
192 | ||
193 | return; | |
194 | ||
195 | } | |
196 | ||
197 | /************************************************************************* | |
198 | * initdram | |
199 | * | |
200 | * Initialize sdram | |
201 | * | |
202 | ************************************************************************/ | |
9973e3c6 | 203 | phys_size_t initdram (int board_type) |
b79316f2 SR |
204 | { |
205 | long dram_size = 0; | |
206 | ||
207 | #if defined(CONFIG_SPD_EEPROM) | |
d87080b7 | 208 | dram_size = spd_sdram (); |
b79316f2 SR |
209 | #else |
210 | dram_size = fixed_sdram (); | |
211 | #endif | |
212 | return dram_size; | |
213 | } | |
214 | ||
215 | ||
216 | /************************************************************************* | |
217 | * testdram | |
218 | * | |
219 | * | |
220 | ************************************************************************/ | |
6d0f6bcf | 221 | #if defined(CONFIG_SYS_DRAM_TEST) |
b79316f2 SR |
222 | int testdram (void) |
223 | { | |
6d0f6bcf JCPV |
224 | uint *pstart = (uint *) CONFIG_SYS_MEMTEST_START; |
225 | uint *pend = (uint *) CONFIG_SYS_MEMTEST_END; | |
b79316f2 SR |
226 | uint *p; |
227 | ||
228 | printf("Testing SDRAM: "); | |
229 | for (p = pstart; p < pend; p++) | |
230 | *p = 0xaaaaaaaa; | |
231 | ||
232 | for (p = pstart; p < pend; p++) { | |
233 | if (*p != 0xaaaaaaaa) { | |
234 | printf ("SDRAM test fails at: %08x\n", (uint) p); | |
235 | return 1; | |
236 | } | |
237 | } | |
238 | ||
239 | for (p = pstart; p < pend; p++) | |
240 | *p = 0x55555555; | |
241 | ||
242 | for (p = pstart; p < pend; p++) { | |
243 | if (*p != 0x55555555) { | |
244 | printf ("SDRAM test fails at: %08x\n", (uint) p); | |
245 | return 1; | |
246 | } | |
247 | } | |
248 | ||
249 | printf("OK\n"); | |
250 | return 0; | |
251 | } | |
252 | #endif | |
253 | ||
254 | #if !defined(CONFIG_SPD_EEPROM) | |
255 | /************************************************************************* | |
256 | * fixed sdram init -- doesn't use serial presence detect. | |
257 | * | |
3d078ce6 WD |
258 | * Assumes: 128 MB, non-ECC, non-registered |
259 | * PLB @ 133 MHz | |
b79316f2 SR |
260 | * |
261 | ************************************************************************/ | |
262 | long int fixed_sdram (void) | |
263 | { | |
264 | uint reg; | |
265 | ||
266 | /*-------------------------------------------------------------------- | |
267 | * Setup some default | |
268 | *------------------------------------------------------------------*/ | |
3d078ce6 WD |
269 | mtsdram (mem_uabba, 0x00000000); /* ubba=0 (default) */ |
270 | mtsdram (mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */ | |
271 | mtsdram (mem_devopt, 0x00000000); /* dll=0 ds=0 (normal) */ | |
272 | mtsdram (mem_wddctr, 0x00000000); /* wrcp=0 dcd=0 */ | |
273 | mtsdram (mem_clktr, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */ | |
b79316f2 SR |
274 | |
275 | /*-------------------------------------------------------------------- | |
276 | * Setup for board-specific specific mem | |
277 | *------------------------------------------------------------------*/ | |
278 | /* | |
279 | * Following for CAS Latency = 2.5 @ 133 MHz PLB | |
280 | */ | |
3d078ce6 WD |
281 | mtsdram (mem_b0cr, 0x000a4001); /* SDBA=0x000 128MB, Mode 3, enabled */ |
282 | mtsdram (mem_tr0, 0x410a4012); /* WR=2 WD=1 CL=2.5 PA=3 CP=4 LD=2 */ | |
283 | /* RA=10 RD=3 */ | |
b79316f2 | 284 | mtsdram (mem_tr1, 0x8080082f); /* SS=T2 SL=STAGE 3 CD=1 CT=0x02f */ |
3d078ce6 WD |
285 | mtsdram (mem_rtr, 0x08200000); /* Rate 15.625 ns @ 133 MHz PLB */ |
286 | mtsdram (mem_cfg1, 0x00000000); /* Self-refresh exit, disable PM */ | |
287 | udelay (400); /* Delay 200 usecs (min) */ | |
b79316f2 SR |
288 | |
289 | /*-------------------------------------------------------------------- | |
290 | * Enable the controller, then wait for DCEN to complete | |
291 | *------------------------------------------------------------------*/ | |
3d078ce6 | 292 | mtsdram (mem_cfg0, 0x86000000); /* DCEN=1, PMUD=1, 64-bit */ |
b79316f2 SR |
293 | for (;;) { |
294 | mfsdram (mem_mcsts, reg); | |
295 | if (reg & 0x80000000) | |
296 | break; | |
297 | } | |
298 | ||
3d078ce6 | 299 | return (128 * 1024 * 1024); /* 128 MB */ |
b79316f2 SR |
300 | } |
301 | #endif /* !defined(CONFIG_SPD_EEPROM) */ | |
302 | ||
303 | ||
304 | /************************************************************************* | |
305 | * pci_pre_init | |
306 | * | |
307 | * This routine is called just prior to registering the hose and gives | |
308 | * the board the opportunity to check things. Returning a value of zero | |
309 | * indicates that things are bad & PCI initialization should be aborted. | |
310 | * | |
311 | * Different boards may wish to customize the pci controller structure | |
312 | * (add regions, override default access routines, etc) or perform | |
313 | * certain pre-initialization actions. | |
314 | * | |
315 | ************************************************************************/ | |
466fff1a | 316 | #if defined(CONFIG_PCI) |
b79316f2 SR |
317 | int pci_pre_init(struct pci_controller * hose ) |
318 | { | |
319 | unsigned long strap; | |
320 | ||
321 | /*--------------------------------------------------------------------------+ | |
322 | * The metrobox is always configured as the host & requires the | |
323 | * PCI arbiter to be enabled. | |
324 | *--------------------------------------------------------------------------*/ | |
325 | mfsdr(sdr_sdstp1, strap); | |
326 | if( (strap & SDR0_SDSTP1_PAE_MASK) == 0 ){ | |
327 | printf("PCI: SDR0_STRP1[%08lX] - PCI Arbiter disabled.\n",strap); | |
328 | return 0; | |
329 | } | |
330 | ||
331 | return 1; | |
332 | } | |
466fff1a | 333 | #endif /* defined(CONFIG_PCI) */ |
b79316f2 SR |
334 | |
335 | /************************************************************************* | |
336 | * pci_target_init | |
337 | * | |
338 | * The bootstrap configuration provides default settings for the pci | |
339 | * inbound map (PIM). But the bootstrap config choices are limited and | |
340 | * may not be sufficient for a given board. | |
341 | * | |
342 | ************************************************************************/ | |
6d0f6bcf | 343 | #if defined(CONFIG_PCI) && defined(CONFIG_SYS_PCI_TARGET_INIT) |
b79316f2 SR |
344 | void pci_target_init(struct pci_controller * hose ) |
345 | { | |
b79316f2 SR |
346 | /*--------------------------------------------------------------------------+ |
347 | * Disable everything | |
348 | *--------------------------------------------------------------------------*/ | |
349 | out32r( PCIX0_PIM0SA, 0 ); /* disable */ | |
350 | out32r( PCIX0_PIM1SA, 0 ); /* disable */ | |
351 | out32r( PCIX0_PIM2SA, 0 ); /* disable */ | |
352 | out32r( PCIX0_EROMBA, 0 ); /* disable expansion rom */ | |
353 | ||
354 | /*--------------------------------------------------------------------------+ | |
355 | * Map all of SDRAM to PCI address 0x0000_0000. Note that the 440 strapping | |
356 | * options to not support sizes such as 128/256 MB. | |
357 | *--------------------------------------------------------------------------*/ | |
6d0f6bcf | 358 | out32r( PCIX0_PIM0LAL, CONFIG_SYS_SDRAM_BASE ); |
b79316f2 SR |
359 | out32r( PCIX0_PIM0LAH, 0 ); |
360 | out32r( PCIX0_PIM0SA, ~(gd->ram_size - 1) | 1 ); | |
361 | ||
362 | out32r( PCIX0_BAR0, 0 ); | |
363 | ||
364 | /*--------------------------------------------------------------------------+ | |
365 | * Program the board's subsystem id/vendor id | |
366 | *--------------------------------------------------------------------------*/ | |
6d0f6bcf JCPV |
367 | out16r( PCIX0_SBSYSVID, CONFIG_SYS_PCI_SUBSYS_VENDORID ); |
368 | out16r( PCIX0_SBSYSID, CONFIG_SYS_PCI_SUBSYS_DEVICEID ); | |
b79316f2 SR |
369 | |
370 | out16r( PCIX0_CMD, in16r(PCIX0_CMD) | PCI_COMMAND_MEMORY ); | |
371 | } | |
6d0f6bcf | 372 | #endif /* defined(CONFIG_PCI) && defined(CONFIG_SYS_PCI_TARGET_INIT) */ |
b79316f2 SR |
373 | |
374 | ||
375 | /************************************************************************* | |
376 | * is_pci_host | |
377 | * | |
378 | * | |
379 | ************************************************************************/ | |
380 | #if defined(CONFIG_PCI) | |
381 | int is_pci_host(struct pci_controller *hose) | |
382 | { | |
383 | /* The metrobox is always configured as host. */ | |
384 | return(1); | |
385 | } | |
386 | #endif /* defined(CONFIG_PCI) */ | |
387 | ||
388 | /************************************************************************* | |
389 | * board_get_enetaddr | |
390 | * | |
391 | * Get the ethernet MAC address for the management ethernet from the | |
392 | * strap EEPROM. Note that is the BASE address for the range of | |
393 | * external ethernet MACs on the board. The base + 31 is the actual | |
394 | * mgmt mac address. | |
395 | * | |
396 | ************************************************************************/ | |
397 | static int macaddr_idx = 0; | |
398 | ||
399 | void board_get_enetaddr (uchar * enet) | |
400 | { | |
401 | int i; | |
402 | unsigned short tmp; | |
403 | unsigned char buff[0x100], *cp; | |
404 | ||
405 | if (0 == macaddr_idx) { | |
406 | ||
407 | /* Initialize I2C */ | |
6d0f6bcf | 408 | i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); |
b79316f2 SR |
409 | |
410 | /* Read 256 bytes in EEPROM */ | |
411 | i2c_read (0x50, 0, 1, buff, 0x100); | |
412 | ||
413 | cp = &buff[0xF0]; | |
414 | ||
415 | for (i = 0; i < 6; i++,cp++) | |
416 | enet[i] = *cp; | |
417 | ||
418 | memcpy(&tmp, &enet[4], 2); | |
419 | tmp += 31; | |
420 | memcpy(&enet[4], &tmp, 2); | |
421 | ||
422 | macaddr_idx++; | |
423 | } else { | |
424 | enet[0] = 0x02; | |
425 | enet[1] = 0x00; | |
426 | enet[2] = 0x00; | |
427 | enet[3] = 0x00; | |
428 | enet[4] = 0x00; | |
429 | if (1 == sbcommon_get_master() ) { | |
430 | /* Master/Primary card */ | |
431 | enet[5] = 0x01; | |
432 | } else { | |
433 | /* Slave/Secondary card */ | |
434 | enet [5] = 0x02; | |
435 | } | |
436 | } | |
437 | ||
438 | return; | |
439 | } | |
440 | ||
441 | #ifdef CONFIG_POST | |
442 | /* | |
443 | * Returns 1 if keys pressed to start the power-on long-running tests | |
444 | * Called from board_init_f(). | |
445 | */ | |
446 | int post_hotkeys_pressed(void) | |
447 | { | |
448 | ||
449 | return (ctrlc()); | |
450 | } | |
451 | #endif |