blob: 90e99d3dca88997256219823c58777cb1c533829 [file] [log] [blame]
Stefan Roesea4c8d132006-06-02 16:18:04 +02001/*
2 * (C) Copyright 2006
3 * Stefan Roese, DENX Software Engineering, sr@denx.de.
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
24#include <common.h>
25#include <ppc4xx.h>
Heiko Schocher566a4942007-06-22 19:11:54 +020026#include <malloc.h>
27#include <command.h>
28#include <crc.h>
Stefan Roesea4c8d132006-06-02 16:18:04 +020029#include <asm/processor.h>
30#include <spd_sdram.h>
Heiko Schocher566a4942007-06-22 19:11:54 +020031#include <status_led.h>
32#include <sha1.h>
Heiko Schocherf98984c2007-08-28 17:39:14 +020033#include <asm/io.h>
Stefan Roesea4c8d132006-06-02 16:18:04 +020034
35DECLARE_GLOBAL_DATA_PTR;
36
37extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
38
Heiko Schocher566a4942007-06-22 19:11:54 +020039unsigned char sha1_checksum[SHA1_SUM_LEN];
40
41/* swap 4 Bits (Bit0 = Bit3, Bit1 = Bit2, Bit2 = Bit1 and Bit3 = Bit0) */
42unsigned char swapbits[16] = {0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
43 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf};
44
45static void set_leds (int val)
Stefan Roesea4c8d132006-06-02 16:18:04 +020046{
Heiko Schocher566a4942007-06-22 19:11:54 +020047 out32(GPIO0_OR, (in32 (GPIO0_OR) & ~0x78000000) | (val << 27));
Stefan Roesea4c8d132006-06-02 16:18:04 +020048}
49
Heiko Schocher566a4942007-06-22 19:11:54 +020050#define GET_LEDS ((in32 (GPIO0_OR) & 0x78000000) >> 27)
51
52void __led_init (led_id_t mask, int state)
53{
54 int val = GET_LEDS;
55
56 if (state == STATUS_LED_ON)
57 val |= mask;
58 else
59 val &= ~mask;
60 set_leds (val);
61}
62
63void __led_set (led_id_t mask, int state)
64{
65 int val = GET_LEDS;
66
67 if (state == STATUS_LED_ON)
68 val |= mask;
69 else if (state == STATUS_LED_OFF)
70 val &= ~mask;
71 set_leds (val);
72}
73
74void __led_toggle (led_id_t mask)
75{
76 int val = GET_LEDS;
77
78 val ^= mask;
79 set_leds (val);
80}
81
82static void status_led_blink (void)
83{
84 int i;
85 int val = GET_LEDS;
86
87 /* set all LED which are on, to state BLINKING */
88 for (i = 0; i < 4; i++) {
Heiko Schocher96e1d752007-07-11 18:39:11 +020089 if (val & 0x01) status_led_set (3 - i, STATUS_LED_BLINKING);
90 else status_led_set (3 - i, STATUS_LED_OFF);
91 val = val >> 1;
Heiko Schocher566a4942007-06-22 19:11:54 +020092 }
93}
94
95#if defined(CONFIG_SHOW_BOOT_PROGRESS)
96void show_boot_progress (int val)
97{
98 /* find all valid Codes for val in README */
99 if (val == -30) return;
100 if (val < 0) {
101 /* smthing goes wrong */
102 status_led_blink ();
103 return;
104 }
105 switch (val) {
106 case 1:
107 /* validating Image */
108 status_led_set (0, STATUS_LED_OFF);
109 status_led_set (1, STATUS_LED_ON);
110 status_led_set (2, STATUS_LED_ON);
111 break;
112 case 15:
113 /* booting */
114 status_led_set (0, STATUS_LED_ON);
115 status_led_set (1, STATUS_LED_ON);
116 status_led_set (2, STATUS_LED_ON);
117 break;
Heiko Schocher96e1d752007-07-11 18:39:11 +0200118#if 0
Heiko Schocher566a4942007-06-22 19:11:54 +0200119 case 64:
120 /* starting Ethernet configuration */
121 status_led_set (0, STATUS_LED_OFF);
122 status_led_set (1, STATUS_LED_OFF);
123 status_led_set (2, STATUS_LED_ON);
124 break;
Heiko Schocher96e1d752007-07-11 18:39:11 +0200125#endif
Heiko Schocher566a4942007-06-22 19:11:54 +0200126 case 80:
127 /* loading Image */
128 status_led_set (0, STATUS_LED_ON);
129 status_led_set (1, STATUS_LED_OFF);
130 status_led_set (2, STATUS_LED_ON);
131 break;
132 }
133}
134#endif
135
Stefan Roesea4c8d132006-06-02 16:18:04 +0200136int board_early_init_f(void)
137{
138 register uint reg;
139
140 set_leds(0); /* display boot info counter */
141
142 /*--------------------------------------------------------------------
143 * Setup the external bus controller/chip selects
144 *-------------------------------------------------------------------*/
145 mtdcr(ebccfga, xbcfg);
146 reg = mfdcr(ebccfgd);
147 mtdcr(ebccfgd, reg | 0x04000000); /* Set ATC */
148
149 /*--------------------------------------------------------------------
150 * GPIO's are alreay setup in cpu/ppc4xx/cpu_init.c
151 * via define from board config file.
152 *-------------------------------------------------------------------*/
153
154 /*--------------------------------------------------------------------
155 * Setup the interrupt controller polarities, triggers, etc.
156 *-------------------------------------------------------------------*/
157 mtdcr(uic0sr, 0xffffffff); /* clear all */
158 mtdcr(uic0er, 0x00000000); /* disable all */
159 mtdcr(uic0cr, 0x00000001); /* UIC1 crit is critical */
160 mtdcr(uic0pr, 0xfffffe1f); /* per ref-board manual */
161 mtdcr(uic0tr, 0x01c00000); /* per ref-board manual */
162 mtdcr(uic0vr, 0x00000001); /* int31 highest, base=0x000 */
163 mtdcr(uic0sr, 0xffffffff); /* clear all */
164
165 mtdcr(uic1sr, 0xffffffff); /* clear all */
166 mtdcr(uic1er, 0x00000000); /* disable all */
167 mtdcr(uic1cr, 0x00000000); /* all non-critical */
168 mtdcr(uic1pr, 0xffffe0ff); /* per ref-board manual */
169 mtdcr(uic1tr, 0x00ffc000); /* per ref-board manual */
170 mtdcr(uic1vr, 0x00000001); /* int31 highest, base=0x000 */
171 mtdcr(uic1sr, 0xffffffff); /* clear all */
172
173 /*--------------------------------------------------------------------
174 * Setup other serial configuration
175 *-------------------------------------------------------------------*/
176 mfsdr(sdr_pci0, reg);
177 mtsdr(sdr_pci0, 0x80000000 | reg); /* PCI arbiter enabled */
178 mtsdr(sdr_pfc0, 0x00000100); /* Pin function: enable GPIO49-63 */
179 mtsdr(sdr_pfc1, 0x00048000); /* Pin function: UART0 has 4 pins, select IRQ5 */
180
181 return 0;
182}
183
Heiko Schocher566a4942007-06-22 19:11:54 +0200184#define EEPROM_LEN 256
185void load_sernum_ethaddr (void)
186{
187 int ret;
188 char buf[EEPROM_LEN];
189 char mac[32];
190 char *use_eeprom;
191 u16 checksumcrc16 = 0;
192
193 /* read the MACs from EEprom */
194 status_led_set (0, STATUS_LED_ON);
195 status_led_set (1, STATUS_LED_ON);
196 ret = eeprom_read (CFG_I2C_EEPROM_ADDR, 0, (uchar *)buf, EEPROM_LEN);
197 if (ret == 0) {
198 checksumcrc16 = cyg_crc16 ((uchar *)buf, EEPROM_LEN - 2);
199 /* check, if the EEprom is programmed:
200 * - The Prefix(Byte 0,1,2) is equal to "ATR"
201 * - The checksum, stored in the last 2 Bytes, is correct
202 */
203 if ((strncmp (buf,"ATR",3) != 0) ||
Wolfgang Denk4ef218f2007-07-10 00:01:28 +0200204 ((checksumcrc16 >> 8) != buf[EEPROM_LEN - 2]) ||
205 ((checksumcrc16 & 0xff) != buf[EEPROM_LEN - 1])) {
Heiko Schocher566a4942007-06-22 19:11:54 +0200206 /* EEprom is not programmed */
207 printf("%s: EEPROM Checksum not OK\n", __FUNCTION__);
208 } else {
209 /* get the MACs */
Wolfgang Denk4ef218f2007-07-10 00:01:28 +0200210 sprintf (mac, "%02x:%02x:%02x:%02x:%02x:%02x",
Heiko Schocher566a4942007-06-22 19:11:54 +0200211 buf[3],
212 buf[4],
213 buf[5],
214 buf[6],
215 buf[7],
216 buf[8]);
217 setenv ("ethaddr", (char *) mac);
Wolfgang Denk4ef218f2007-07-10 00:01:28 +0200218 sprintf (mac, "%02x:%02x:%02x:%02x:%02x:%02x",
Heiko Schocher566a4942007-06-22 19:11:54 +0200219 buf[9],
220 buf[10],
221 buf[11],
222 buf[12],
223 buf[13],
224 buf[14]);
225 setenv ("eth1addr", (char *) mac);
226 return;
227 }
228 }
229
230 /* some error reading the EEprom */
231 if ((use_eeprom = getenv ("use_eeprom_ethaddr")) == NULL) {
232 /* dont use bootcmd */
233 setenv("bootdelay", "-1");
234 return;
235 }
236 /* == default ? use standard */
237 if (strncmp (use_eeprom, "default", 7) == 0) {
238 return;
239 }
240 /* Env doesnt exist -> hang */
241 status_led_blink ();
Heiko Schocher90790242007-07-13 08:26:05 +0200242 /* here we do this "handy" because we have no interrupts
243 at this time */
244 puts ("### EEPROM ERROR ### Please RESET the board ###\n");
245 for (;;) {
246 __led_toggle (12);
247 udelay (100000);
248 }
Heiko Schocher566a4942007-06-22 19:11:54 +0200249 return;
250}
251
252#ifdef CONFIG_PREBOOT
253
254static uchar kbd_magic_prefix[] = "key_magic";
255static uchar kbd_command_prefix[] = "key_cmd";
256
257struct kbd_data_t {
258 char s1;
259 char s2;
260};
261
262struct kbd_data_t* get_keys (struct kbd_data_t *kbd_data)
263{
264 char *val;
265 unsigned long tmp;
266
267 /* use the DIPs for some bootoptions */
268 val = getenv (ENV_NAME_DIP);
269 tmp = simple_strtoul (val, NULL, 16);
270
271 kbd_data->s2 = (tmp & 0x0f);
272 kbd_data->s1 = (tmp & 0xf0) >> 4;
273 return kbd_data;
274}
275
276static int compare_magic (const struct kbd_data_t *kbd_data, char *str)
277{
278 char s1 = str[0];
279
280 if (s1 >= '0' && s1 <= '9')
281 s1 -= '0';
282 else if (s1 >= 'a' && s1 <= 'f')
283 s1 = s1 - 'a' + 10;
284 else if (s1 >= 'A' && s1 <= 'F')
285 s1 = s1 - 'A' + 10;
286 else
287 return -1;
288
289 if (s1 != kbd_data->s1) return -1;
290
291 s1 = str[1];
292 if (s1 >= '0' && s1 <= '9')
293 s1 -= '0';
294 else if (s1 >= 'a' && s1 <= 'f')
295 s1 = s1 - 'a' + 10;
296 else if (s1 >= 'A' && s1 <= 'F')
297 s1 = s1 - 'A' + 10;
298 else
299 return -1;
300
301 if (s1 != kbd_data->s2) return -1;
302 return 0;
303}
304
305static char *key_match (const struct kbd_data_t *kbd_data)
306{
307 char magic[sizeof (kbd_magic_prefix) + 1];
308 char *suffix;
309 char *kbd_magic_keys;
310
311 /*
312 * The following string defines the characters that can be appended
313 * to "key_magic" to form the names of environment variables that
314 * hold "magic" key codes, i. e. such key codes that can cause
315 * pre-boot actions. If the string is empty (""), then only
316 * "key_magic" is checked (old behaviour); the string "125" causes
317 * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
318 */
319 if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
320 kbd_magic_keys = "";
321
322 /* loop over all magic keys;
323 * use '\0' suffix in case of empty string
324 */
325 for (suffix = kbd_magic_keys; *suffix ||
326 suffix == kbd_magic_keys; ++suffix) {
327 sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
328 if (compare_magic (kbd_data, getenv (magic)) == 0) {
329 char cmd_name[sizeof (kbd_command_prefix) + 1];
330 char *cmd;
331
332 sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
333 cmd = getenv (cmd_name);
334
335 return (cmd);
336 }
337 }
338 return (NULL);
339}
340
341#endif /* CONFIG_PREBOOT */
342
343static int pcs440ep_readinputs (void)
344{
345 int i;
346 char value[20];
347
348 /* read the inputs and set the Envvars */
349 /* Revision Level Bit 26 - 29 */
350 i = ((in32 (GPIO0_IR) & 0x0000003c) >> 2);
351 i = swapbits[i];
352 sprintf (value, "%02x", i);
353 setenv (ENV_NAME_REVLEV, value);
354 /* Solder Switch Bit 30 - 33 */
355 i = (in32 (GPIO0_IR) & 0x00000003) << 2;
356 i += (in32 (GPIO1_IR) & 0xc0000000) >> 30;
357 i = swapbits[i];
358 sprintf (value, "%02x", i);
359 setenv (ENV_NAME_SOLDER, value);
360 /* DIP Switch Bit 49 - 56 */
361 i = ((in32 (GPIO1_IR) & 0x00007f80) >> 7);
362 i = (swapbits[i & 0x0f] << 4) + swapbits[(i & 0xf0) >> 4];
363 sprintf (value, "%02x", i);
364 setenv (ENV_NAME_DIP, value);
365 return 0;
366}
367
368
369#if defined(CONFIG_SHA1_CHECK_UB_IMG)
370/*************************************************************************
371 * calculate a SHA1 sum for the U-Boot image in Flash.
372 *
373 ************************************************************************/
374static int pcs440ep_sha1 (int docheck)
375{
376 unsigned char *data;
377 unsigned char *ptroff;
378 unsigned char output[20];
379 unsigned char org[20];
380 int i, len = CONFIG_SHA1_LEN;
381
382 memcpy ((char *)CFG_LOAD_ADDR, (char *)CONFIG_SHA1_START, len);
383 data = (unsigned char *)CFG_LOAD_ADDR;
384 ptroff = &data[len + SHA1_SUM_POS];
385
386 for (i = 0; i < SHA1_SUM_LEN; i++) {
387 org[i] = ptroff[i];
388 ptroff[i] = 0;
389 }
Wolfgang Denk4ef218f2007-07-10 00:01:28 +0200390
Heiko Schocher566a4942007-06-22 19:11:54 +0200391 sha1_csum ((unsigned char *) data, len, (unsigned char *)output);
392
393 if (docheck == 2) {
394 for (i = 0; i < 20 ; i++) {
395 printf("%02X ", output[i]);
396 }
397 printf("\n");
398 }
399 if (docheck == 1) {
400 for (i = 0; i < 20 ; i++) {
401 if (org[i] != output[i]) return 1;
402 }
403 }
404 return 0;
405}
406
407/*************************************************************************
408 * do some checks after the SHA1 checksum from the U-Boot Image was
409 * calculated.
410 *
411 ************************************************************************/
412static void pcs440ep_checksha1 (void)
413{
414 int ret;
415 char *cs_test;
416
Heiko Schocher96e1d752007-07-11 18:39:11 +0200417 status_led_set (0, STATUS_LED_OFF);
418 status_led_set (1, STATUS_LED_OFF);
419 status_led_set (2, STATUS_LED_ON);
Heiko Schocher566a4942007-06-22 19:11:54 +0200420 ret = pcs440ep_sha1 (1);
421 if (ret == 0) return;
422
423 if ((cs_test = getenv ("cs_test")) == NULL) {
424 /* Env doesnt exist -> hang */
425 status_led_blink ();
Heiko Schocher90790242007-07-13 08:26:05 +0200426 /* here we do this "handy" because we have no interrupts
427 at this time */
428 puts ("### SHA1 ERROR ### Please RESET the board ###\n");
429 for (;;) {
430 __led_toggle (2);
431 udelay (100000);
432 }
Heiko Schocher566a4942007-06-22 19:11:54 +0200433 }
434
435 if (strncmp (cs_test, "off", 3) == 0) {
436 printf ("SHA1 U-Boot sum NOT ok!\n");
437 setenv ("bootdelay", "-1");
438 }
439}
440#else
441static __inline__ void pcs440ep_checksha1 (void) { do {} while (0);}
442#endif
443
Stefan Roesea4c8d132006-06-02 16:18:04 +0200444int misc_init_r (void)
445{
446 uint pbcr;
447 int size_val = 0;
448
449 /* Re-do sizing to get full correct info */
450 mtdcr(ebccfga, pb0cr);
451 pbcr = mfdcr(ebccfgd);
452 switch (gd->bd->bi_flashsize) {
453 case 1 << 20:
454 size_val = 0;
455 break;
456 case 2 << 20:
457 size_val = 1;
458 break;
459 case 4 << 20:
460 size_val = 2;
461 break;
462 case 8 << 20:
463 size_val = 3;
464 break;
465 case 16 << 20:
466 size_val = 4;
467 break;
468 case 32 << 20:
469 size_val = 5;
470 break;
471 case 64 << 20:
472 size_val = 6;
473 break;
474 case 128 << 20:
475 size_val = 7;
476 break;
477 }
478 pbcr = (pbcr & 0x0001ffff) | gd->bd->bi_flashstart | (size_val << 17);
479 mtdcr(ebccfga, pb0cr);
480 mtdcr(ebccfgd, pbcr);
481
482 /* adjust flash start and offset */
483 gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
484 gd->bd->bi_flashoffset = 0;
485
486 /* Monitor protection ON by default */
487 (void)flash_protect(FLAG_PROTECT_SET,
488 -CFG_MONITOR_LEN,
489 0xffffffff,
490 &flash_info[1]);
491
492 /* Env protection ON by default */
493 (void)flash_protect(FLAG_PROTECT_SET,
494 CFG_ENV_ADDR_REDUND,
495 CFG_ENV_ADDR_REDUND + 2*CFG_ENV_SECT_SIZE - 1,
Stefan Roese4526c872006-06-06 10:59:12 +0200496 &flash_info[1]);
Stefan Roesea4c8d132006-06-02 16:18:04 +0200497
Heiko Schocher566a4942007-06-22 19:11:54 +0200498 pcs440ep_readinputs ();
499 pcs440ep_checksha1 ();
500#ifdef CONFIG_PREBOOT
501 {
502 struct kbd_data_t kbd_data;
503 /* Decode keys */
504 char *str = strdup (key_match (get_keys (&kbd_data)));
505 /* Set or delete definition */
506 setenv ("preboot", str);
507 free (str);
508 }
509#endif /* CONFIG_PREBOOT */
Stefan Roesea4c8d132006-06-02 16:18:04 +0200510 return 0;
511}
512
513int checkboard(void)
514{
515 char *s = getenv("serial#");
516
517 printf("Board: PCS440EP");
518 if (s != NULL) {
519 puts(", serial# ");
520 puts(s);
521 }
522 putc('\n');
523
524 return (0);
525}
526
Heiko Schocher566a4942007-06-22 19:11:54 +0200527void spd_ddr_init_hang (void)
528{
529 status_led_set (0, STATUS_LED_OFF);
530 status_led_set (1, STATUS_LED_ON);
531 /* we cannot use hang() because we are still running from
532 Flash, and so the status_led driver is not initialized */
Heiko Schocher90790242007-07-13 08:26:05 +0200533 puts ("### SDRAM ERROR ### Please RESET the board ###\n");
Heiko Schocher566a4942007-06-22 19:11:54 +0200534 for (;;) {
535 __led_toggle (4);
536 udelay (100000);
537 }
538}
Heiko Schocher566a4942007-06-22 19:11:54 +0200539
Stefan Roesea4c8d132006-06-02 16:18:04 +0200540long int initdram (int board_type)
541{
542 long dram_size = 0;
543
Heiko Schocher566a4942007-06-22 19:11:54 +0200544 status_led_set (0, STATUS_LED_ON);
545 status_led_set (1, STATUS_LED_OFF);
Stefan Roesea4c8d132006-06-02 16:18:04 +0200546 dram_size = spd_sdram();
Heiko Schocher566a4942007-06-22 19:11:54 +0200547 status_led_set (0, STATUS_LED_OFF);
548 status_led_set (1, STATUS_LED_ON);
549 if (dram_size == 0) {
550 hang();
551 }
Stefan Roesea4c8d132006-06-02 16:18:04 +0200552
553 return dram_size;
554}
555
556#if defined(CFG_DRAM_TEST)
557int testdram(void)
558{
559 unsigned long *mem = (unsigned long *)0;
560 const unsigned long kend = (1024 / sizeof(unsigned long));
561 unsigned long k, n;
562
563 mtmsr(0);
564
565 for (k = 0; k < CFG_KBYTES_SDRAM;
566 ++k, mem += (1024 / sizeof(unsigned long))) {
567 if ((k & 1023) == 0) {
568 printf("%3d MB\r", k / 1024);
569 }
570
571 memset(mem, 0xaaaaaaaa, 1024);
572 for (n = 0; n < kend; ++n) {
573 if (mem[n] != 0xaaaaaaaa) {
574 printf("SDRAM test fails at: %08x\n",
575 (uint) & mem[n]);
576 return 1;
577 }
578 }
579
580 memset(mem, 0x55555555, 1024);
581 for (n = 0; n < kend; ++n) {
582 if (mem[n] != 0x55555555) {
583 printf("SDRAM test fails at: %08x\n",
584 (uint) & mem[n]);
585 return 1;
586 }
587 }
588 }
589 printf("SDRAM test passes\n");
590 return 0;
591}
592#endif
593
594/*************************************************************************
595 * pci_pre_init
596 *
597 * This routine is called just prior to registering the hose and gives
598 * the board the opportunity to check things. Returning a value of zero
599 * indicates that things are bad & PCI initialization should be aborted.
600 *
601 * Different boards may wish to customize the pci controller structure
602 * (add regions, override default access routines, etc) or perform
603 * certain pre-initialization actions.
604 *
605 ************************************************************************/
Stefan Roese466fff12007-06-25 15:57:39 +0200606#if defined(CONFIG_PCI)
Stefan Roesea4c8d132006-06-02 16:18:04 +0200607int pci_pre_init(struct pci_controller *hose)
608{
609 unsigned long addr;
610
611 /*-------------------------------------------------------------------------+
612 | Set priority for all PLB3 devices to 0.
613 | Set PLB3 arbiter to fair mode.
614 +-------------------------------------------------------------------------*/
615 mfsdr(sdr_amp1, addr);
616 mtsdr(sdr_amp1, (addr & 0x000000FF) | 0x0000FF00);
617 addr = mfdcr(plb3_acr);
618 mtdcr(plb3_acr, addr | 0x80000000);
619
620 /*-------------------------------------------------------------------------+
621 | Set priority for all PLB4 devices to 0.
622 +-------------------------------------------------------------------------*/
623 mfsdr(sdr_amp0, addr);
624 mtsdr(sdr_amp0, (addr & 0x000000FF) | 0x0000FF00);
625 addr = mfdcr(plb4_acr) | 0xa0000000; /* Was 0x8---- */
626 mtdcr(plb4_acr, addr);
627
628 /*-------------------------------------------------------------------------+
629 | Set Nebula PLB4 arbiter to fair mode.
630 +-------------------------------------------------------------------------*/
631 /* Segment0 */
632 addr = (mfdcr(plb0_acr) & ~plb0_acr_ppm_mask) | plb0_acr_ppm_fair;
633 addr = (addr & ~plb0_acr_hbu_mask) | plb0_acr_hbu_enabled;
634 addr = (addr & ~plb0_acr_rdp_mask) | plb0_acr_rdp_4deep;
635 addr = (addr & ~plb0_acr_wrp_mask) | plb0_acr_wrp_2deep;
636 mtdcr(plb0_acr, addr);
637
638 /* Segment1 */
639 addr = (mfdcr(plb1_acr) & ~plb1_acr_ppm_mask) | plb1_acr_ppm_fair;
640 addr = (addr & ~plb1_acr_hbu_mask) | plb1_acr_hbu_enabled;
641 addr = (addr & ~plb1_acr_rdp_mask) | plb1_acr_rdp_4deep;
642 addr = (addr & ~plb1_acr_wrp_mask) | plb1_acr_wrp_2deep;
643 mtdcr(plb1_acr, addr);
644
645 return 1;
646}
Stefan Roese466fff12007-06-25 15:57:39 +0200647#endif /* defined(CONFIG_PCI) */
Stefan Roesea4c8d132006-06-02 16:18:04 +0200648
649/*************************************************************************
650 * pci_target_init
651 *
652 * The bootstrap configuration provides default settings for the pci
653 * inbound map (PIM). But the bootstrap config choices are limited and
654 * may not be sufficient for a given board.
655 *
656 ************************************************************************/
657#if defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT)
658void pci_target_init(struct pci_controller *hose)
659{
660 /*--------------------------------------------------------------------------+
661 * Set up Direct MMIO registers
662 *--------------------------------------------------------------------------*/
663 /*--------------------------------------------------------------------------+
664 | PowerPC440 EP PCI Master configuration.
665 | Map one 1Gig range of PLB/processor addresses to PCI memory space.
666 | PLB address 0xA0000000-0xDFFFFFFF ==> PCI address 0xA0000000-0xDFFFFFFF
667 | Use byte reversed out routines to handle endianess.
668 | Make this region non-prefetchable.
669 +--------------------------------------------------------------------------*/
670 out32r(PCIX0_PMM0MA, 0x00000000); /* PMM0 Mask/Attribute - disabled b4 setting */
671 out32r(PCIX0_PMM0LA, CFG_PCI_MEMBASE); /* PMM0 Local Address */
672 out32r(PCIX0_PMM0PCILA, CFG_PCI_MEMBASE); /* PMM0 PCI Low Address */
673 out32r(PCIX0_PMM0PCIHA, 0x00000000); /* PMM0 PCI High Address */
674 out32r(PCIX0_PMM0MA, 0xE0000001); /* 512M + No prefetching, and enable region */
675
676 out32r(PCIX0_PMM1MA, 0x00000000); /* PMM0 Mask/Attribute - disabled b4 setting */
677 out32r(PCIX0_PMM1LA, CFG_PCI_MEMBASE2); /* PMM0 Local Address */
678 out32r(PCIX0_PMM1PCILA, CFG_PCI_MEMBASE2); /* PMM0 PCI Low Address */
679 out32r(PCIX0_PMM1PCIHA, 0x00000000); /* PMM0 PCI High Address */
680 out32r(PCIX0_PMM1MA, 0xE0000001); /* 512M + No prefetching, and enable region */
681
682 out32r(PCIX0_PTM1MS, 0x00000001); /* Memory Size/Attribute */
683 out32r(PCIX0_PTM1LA, 0); /* Local Addr. Reg */
684 out32r(PCIX0_PTM2MS, 0); /* Memory Size/Attribute */
685 out32r(PCIX0_PTM2LA, 0); /* Local Addr. Reg */
686
687 /*--------------------------------------------------------------------------+
688 * Set up Configuration registers
689 *--------------------------------------------------------------------------*/
690
691 /* Program the board's subsystem id/vendor id */
692 pci_write_config_word(0, PCI_SUBSYSTEM_VENDOR_ID,
693 CFG_PCI_SUBSYS_VENDORID);
694 pci_write_config_word(0, PCI_SUBSYSTEM_ID, CFG_PCI_SUBSYS_ID);
695
696 /* Configure command register as bus master */
697 pci_write_config_word(0, PCI_COMMAND, PCI_COMMAND_MASTER);
698
699 /* 240nS PCI clock */
700 pci_write_config_word(0, PCI_LATENCY_TIMER, 1);
701
702 /* No error reporting */
703 pci_write_config_word(0, PCI_ERREN, 0);
704
705 pci_write_config_dword(0, PCI_BRDGOPT2, 0x00000101);
706
707}
708#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */
709
710/*************************************************************************
711 * pci_master_init
712 *
713 ************************************************************************/
714#if defined(CONFIG_PCI) && defined(CFG_PCI_MASTER_INIT)
715void pci_master_init(struct pci_controller *hose)
716{
717 unsigned short temp_short;
718
719 /*--------------------------------------------------------------------------+
720 | Write the PowerPC440 EP PCI Configuration regs.
721 | Enable PowerPC440 EP to be a master on the PCI bus (PMM).
722 | Enable PowerPC440 EP to act as a PCI memory target (PTM).
723 +--------------------------------------------------------------------------*/
724 pci_read_config_word(0, PCI_COMMAND, &temp_short);
725 pci_write_config_word(0, PCI_COMMAND,
726 temp_short | PCI_COMMAND_MASTER |
727 PCI_COMMAND_MEMORY);
728}
729#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_MASTER_INIT) */
730
731/*************************************************************************
732 * is_pci_host
733 *
734 * This routine is called to determine if a pci scan should be
735 * performed. With various hardware environments (especially cPCI and
736 * PPMC) it's insufficient to depend on the state of the arbiter enable
737 * bit in the strap register, or generic host/adapter assumptions.
738 *
739 * Rather than hard-code a bad assumption in the general 440 code, the
740 * 440 pci code requires the board to decide at runtime.
741 *
742 * Return 0 for adapter mode, non-zero for host (monarch) mode.
743 *
744 *
745 ************************************************************************/
746#if defined(CONFIG_PCI)
747int is_pci_host(struct pci_controller *hose)
748{
749 /* PCS440EP is always configured as host. */
750 return (1);
751}
752#endif /* defined(CONFIG_PCI) */
753
754/*************************************************************************
755 * hw_watchdog_reset
756 *
757 * This routine is called to reset (keep alive) the watchdog timer
758 *
759 ************************************************************************/
760#if defined(CONFIG_HW_WATCHDOG)
761void hw_watchdog_reset(void)
762{
763
764}
765#endif
Heiko Schocher566a4942007-06-22 19:11:54 +0200766
767/*************************************************************************
768 * "led" Commando for the U-Boot shell
769 *
770 ************************************************************************/
771int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
772{
Heiko Schocher96e1d752007-07-11 18:39:11 +0200773 int rcode = 0, i;
Heiko Schocher566a4942007-06-22 19:11:54 +0200774 ulong pattern = 0;
775
Heiko Schocher96e1d752007-07-11 18:39:11 +0200776 pattern = simple_strtoul (argv[1], NULL, 16);
777 if (pattern > 0x400) {
778 int val = GET_LEDS;
779 printf ("led: %x\n", val);
780 return rcode;
781 }
782 if (pattern > 0x200) {
Heiko Schocher566a4942007-06-22 19:11:54 +0200783 status_led_blink ();
784 hang ();
785 return rcode;
786 }
Heiko Schocher96e1d752007-07-11 18:39:11 +0200787 if (pattern > 0x100) {
Heiko Schocher566a4942007-06-22 19:11:54 +0200788 status_led_blink ();
789 return rcode;
790 }
791 pattern &= 0x0f;
Heiko Schocher96e1d752007-07-11 18:39:11 +0200792 for (i = 0; i < 4; i++) {
793 if (pattern & 0x01) status_led_set (i, STATUS_LED_ON);
794 else status_led_set (i, STATUS_LED_OFF);
795 pattern = pattern >> 1;
796 }
Heiko Schocher566a4942007-06-22 19:11:54 +0200797 return rcode;
798}
799
800U_BOOT_CMD(
801 led, 2, 1, do_led,
Heiko Schocher96e1d752007-07-11 18:39:11 +0200802 "led [bitmask] - set the DIAG-LED\n",
803 "[bitmask] 0x01 = DIAG 1 on\n"
804 " 0x02 = DIAG 2 on\n"
805 " 0x04 = DIAG 3 on\n"
806 " 0x08 = DIAG 4 on\n"
807 " > 0x100 set the LED, who are on, to state blinking\n"
Heiko Schocher566a4942007-06-22 19:11:54 +0200808);
809
810#if defined(CONFIG_SHA1_CHECK_UB_IMG)
811/*************************************************************************
812 * "sha1" Commando for the U-Boot shell
813 *
814 ************************************************************************/
815int do_sha1 (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
816{
817 int rcode = -1;
818
819 if (argc < 2) {
820 usage:
821 printf ("Usage:\n%s\n", cmdtp->usage);
822 return 1;
823 }
824
825 if (argc >= 3) {
826 unsigned char *data;
827 unsigned char output[20];
828 int len;
829 int i;
Wolfgang Denk4ef218f2007-07-10 00:01:28 +0200830
Heiko Schocher566a4942007-06-22 19:11:54 +0200831 data = (unsigned char *)simple_strtoul (argv[1], NULL, 16);
832 len = simple_strtoul (argv[2], NULL, 16);
833 sha1_csum (data, len, (unsigned char *)output);
834 printf ("U-Boot sum:\n");
835 for (i = 0; i < 20 ; i++) {
836 printf ("%02X ", output[i]);
837 }
838 printf ("\n");
839 if (argc == 4) {
840 data = (unsigned char *)simple_strtoul (argv[3], NULL, 16);
841 memcpy (data, output, 20);
842 }
843 return 0;
844 }
845 if (argc == 2) {
846 char *ptr = argv[1];
847 if (*ptr != '-') goto usage;
848 ptr++;
849 if ((*ptr == 'c') || (*ptr == 'C')) {
850 rcode = pcs440ep_sha1 (1);
851 printf ("SHA1 U-Boot sum %sok!\n", (rcode != 0) ? "not " : "");
852 } else if ((*ptr == 'p') || (*ptr == 'P')) {
853 rcode = pcs440ep_sha1 (2);
854 } else {
855 rcode = pcs440ep_sha1 (0);
856 }
Wolfgang Denk4ef218f2007-07-10 00:01:28 +0200857 return rcode;
Heiko Schocher566a4942007-06-22 19:11:54 +0200858 }
859 return rcode;
860}
861
862U_BOOT_CMD(
863 sha1, 4, 1, do_sha1,
864 "sha1 - calculate the SHA1 Sum\n",
865 "address len [addr] calculate the SHA1 sum [save at addr]\n"
866 " -p calculate the SHA1 sum from the U-Boot image in flash and print\n"
867 " -c check the U-Boot image in flash\n"
868);
869#endif
870
Heiko Schocherf98984c2007-08-28 17:39:14 +0200871#if defined (CONFIG_CMD_IDE)
872/* These addresses need to be shifted one place to the left
873 * ( bus per_addr 20 -30 is connectsd on CF bus A10-A0)
874 * These values are shifted
875 */
876extern ulong *ide_bus_offset;
877void inline ide_outb(int dev, int port, unsigned char val)
878{
879 debug ("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
880 dev, port, val, (ATA_CURR_BASE(dev)+port));
881
882 out_be16((u16 *)(ATA_CURR_BASE(dev)+(port << 1)), val);
883}
884unsigned char inline ide_inb(int dev, int port)
885{
886 uchar val;
887 val = in_be16((u16 *)(ATA_CURR_BASE(dev)+(port << 1)));
888 debug ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n",
889 dev, port, (ATA_CURR_BASE(dev)+port), val);
890 return (val);
891}
892#endif
893
Heiko Schocher566a4942007-06-22 19:11:54 +0200894#ifdef CONFIG_IDE_PREINIT
895int ide_preinit (void)
896{
897 /* Set True IDE Mode */
898 out32 (GPIO0_OR, (in32 (GPIO0_OR) | 0x00100000));
899 out32 (GPIO0_OR, (in32 (GPIO0_OR) | 0x00200000));
900 out32 (GPIO1_OR, (in32 (GPIO1_OR) & ~0x00008040));
901 udelay (100000);
902 return 0;
903}
904#endif
905
Wolfgang Denkafaac862007-08-12 14:27:39 +0200906#if defined (CONFIG_CMD_IDE) && defined (CONFIG_IDE_RESET)
Heiko Schocher566a4942007-06-22 19:11:54 +0200907void ide_set_reset (int idereset)
908{
909 debug ("ide_reset(%d)\n", idereset);
910 if (idereset == 0) {
911 out32 (GPIO0_OR, (in32 (GPIO0_OR) | 0x00200000));
912 } else {
913 out32 (GPIO0_OR, (in32 (GPIO0_OR) & ~0x00200000));
914 }
915 udelay (10000);
916}
Wolfgang Denkafaac862007-08-12 14:27:39 +0200917#endif /* defined (CONFIG_CMD_IDE) && defined (CONFIG_IDE_RESET) */