blob: 01ceecebbb8bfeb843a8e272057ce5f9f2fd32ab [file] [log] [blame]
Stefan Roese9eba0c82006-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 Schocher633e03a2007-06-22 19:11:54 +020026#include <malloc.h>
27#include <command.h>
28#include <crc.h>
Stefan Roese9eba0c82006-06-02 16:18:04 +020029#include <asm/processor.h>
30#include <spd_sdram.h>
Heiko Schocher633e03a2007-06-22 19:11:54 +020031#include <status_led.h>
32#include <sha1.h>
Heiko Schocher2559e0f2007-08-28 17:39:14 +020033#include <asm/io.h>
Stefan Roese9eba0c82006-06-02 16:18:04 +020034
35DECLARE_GLOBAL_DATA_PTR;
36
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020037extern flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
Stefan Roese9eba0c82006-06-02 16:18:04 +020038
Heiko Schocher633e03a2007-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)
46{
47 out32(GPIO0_OR, (in32 (GPIO0_OR) & ~0x78000000) | (val << 27));
48}
49
50#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)
Stefan Roese9eba0c82006-06-02 16:18:04 +020064{
Heiko Schocher633e03a2007-06-22 19:11:54 +020065 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);
Stefan Roese9eba0c82006-06-02 16:18:04 +020072}
73
Heiko Schocher633e03a2007-06-22 19:11:54 +020074void __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)
Stefan Roese9eba0c82006-06-02 16:18:04 +020083{
Heiko Schocher633e03a2007-06-22 19:11:54 +020084 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 Schocher30b4c252007-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 Schocher633e03a2007-06-22 19:11:54 +020092 }
Stefan Roese9eba0c82006-06-02 16:18:04 +020093}
94
Heiko Schocher633e03a2007-06-22 19:11:54 +020095#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 Schocher30b4c252007-07-11 18:39:11 +0200118#if 0
Heiko Schocher633e03a2007-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 Schocher30b4c252007-07-11 18:39:11 +0200125#endif
Heiko Schocher633e03a2007-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 Roese9eba0c82006-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 */
Stefan Roese5dd24ba2008-01-30 15:35:50 +0100178 mtsdr(sdr_pfc0, 0x00000000); /* Pin function: enable GPIO49-63 */
Stefan Roese9eba0c82006-06-02 16:18:04 +0200179 mtsdr(sdr_pfc1, 0x00048000); /* Pin function: UART0 has 4 pins, select IRQ5 */
180
Heiko Schocher633e03a2007-06-22 19:11:54 +0200181 return 0;
182}
183
184#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);
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200196 ret = eeprom_read (CONFIG_SYS_I2C_EEPROM_ADDR, 0, (uchar *)buf, EEPROM_LEN);
Heiko Schocher633e03a2007-06-22 19:11:54 +0200197 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 Denka0453aa2007-07-10 00:01:28 +0200204 ((checksumcrc16 >> 8) != buf[EEPROM_LEN - 2]) ||
205 ((checksumcrc16 & 0xff) != buf[EEPROM_LEN - 1])) {
Heiko Schocher633e03a2007-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 Denka0453aa2007-07-10 00:01:28 +0200210 sprintf (mac, "%02x:%02x:%02x:%02x:%02x:%02x",
Heiko Schocher633e03a2007-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 Denka0453aa2007-07-10 00:01:28 +0200218 sprintf (mac, "%02x:%02x:%02x:%02x:%02x:%02x",
Heiko Schocher633e03a2007-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 Schocher3b1c2d72007-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 Schocher633e03a2007-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
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200382 memcpy ((char *)CONFIG_SYS_LOAD_ADDR, (char *)CONFIG_SHA1_START, len);
383 data = (unsigned char *)CONFIG_SYS_LOAD_ADDR;
Heiko Schocher633e03a2007-06-22 19:11:54 +0200384 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 Denka0453aa2007-07-10 00:01:28 +0200390
Heiko Schocher633e03a2007-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 }
Stefan Roese9eba0c82006-06-02 16:18:04 +0200404 return 0;
405}
406
Heiko Schocher633e03a2007-06-22 19:11:54 +0200407/*************************************************************************
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 Schocher30b4c252007-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 Schocher633e03a2007-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 Schocher3b1c2d72007-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 Schocher633e03a2007-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
Stefan Roese9eba0c82006-06-02 16:18:04 +0200443
444int 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,
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200488 -CONFIG_SYS_MONITOR_LEN,
Stefan Roese9eba0c82006-06-02 16:18:04 +0200489 0xffffffff,
490 &flash_info[1]);
491
492 /* Env protection ON by default */
493 (void)flash_protect(FLAG_PROTECT_SET,
Jean-Christophe PLAGNIOL-VILLARD7e1cda62008-09-10 22:48:06 +0200494 CONFIG_ENV_ADDR_REDUND,
495 CONFIG_ENV_ADDR_REDUND + 2*CONFIG_ENV_SECT_SIZE - 1,
Stefan Roese0cd201c2006-06-06 10:59:12 +0200496 &flash_info[1]);
Stefan Roese9eba0c82006-06-02 16:18:04 +0200497
Heiko Schocher633e03a2007-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 Roese9eba0c82006-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 Schocher633e03a2007-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 Schocher3b1c2d72007-07-13 08:26:05 +0200533 puts ("### SDRAM ERROR ### Please RESET the board ###\n");
Heiko Schocher633e03a2007-06-22 19:11:54 +0200534 for (;;) {
535 __led_toggle (4);
536 udelay (100000);
537 }
538}
Heiko Schocher633e03a2007-06-22 19:11:54 +0200539
Becky Brucebd99ae72008-06-09 16:03:40 -0500540phys_size_t initdram (int board_type)
Stefan Roese9eba0c82006-06-02 16:18:04 +0200541{
542 long dram_size = 0;
543
Heiko Schocher633e03a2007-06-22 19:11:54 +0200544 status_led_set (0, STATUS_LED_ON);
545 status_led_set (1, STATUS_LED_OFF);
Stefan Roese9eba0c82006-06-02 16:18:04 +0200546 dram_size = spd_sdram();
Heiko Schocher633e03a2007-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 Roese9eba0c82006-06-02 16:18:04 +0200552
553 return dram_size;
554}
555
Stefan Roese9eba0c82006-06-02 16:18:04 +0200556/*************************************************************************
557 * pci_pre_init
558 *
559 * This routine is called just prior to registering the hose and gives
560 * the board the opportunity to check things. Returning a value of zero
561 * indicates that things are bad & PCI initialization should be aborted.
562 *
563 * Different boards may wish to customize the pci controller structure
564 * (add regions, override default access routines, etc) or perform
565 * certain pre-initialization actions.
566 *
567 ************************************************************************/
Stefan Roese54ef7fd2007-06-25 15:57:39 +0200568#if defined(CONFIG_PCI)
Stefan Roese9eba0c82006-06-02 16:18:04 +0200569int pci_pre_init(struct pci_controller *hose)
570{
571 unsigned long addr;
572
573 /*-------------------------------------------------------------------------+
574 | Set priority for all PLB3 devices to 0.
575 | Set PLB3 arbiter to fair mode.
576 +-------------------------------------------------------------------------*/
577 mfsdr(sdr_amp1, addr);
578 mtsdr(sdr_amp1, (addr & 0x000000FF) | 0x0000FF00);
579 addr = mfdcr(plb3_acr);
580 mtdcr(plb3_acr, addr | 0x80000000);
581
582 /*-------------------------------------------------------------------------+
583 | Set priority for all PLB4 devices to 0.
584 +-------------------------------------------------------------------------*/
585 mfsdr(sdr_amp0, addr);
586 mtsdr(sdr_amp0, (addr & 0x000000FF) | 0x0000FF00);
587 addr = mfdcr(plb4_acr) | 0xa0000000; /* Was 0x8---- */
588 mtdcr(plb4_acr, addr);
589
590 /*-------------------------------------------------------------------------+
591 | Set Nebula PLB4 arbiter to fair mode.
592 +-------------------------------------------------------------------------*/
593 /* Segment0 */
594 addr = (mfdcr(plb0_acr) & ~plb0_acr_ppm_mask) | plb0_acr_ppm_fair;
595 addr = (addr & ~plb0_acr_hbu_mask) | plb0_acr_hbu_enabled;
596 addr = (addr & ~plb0_acr_rdp_mask) | plb0_acr_rdp_4deep;
597 addr = (addr & ~plb0_acr_wrp_mask) | plb0_acr_wrp_2deep;
598 mtdcr(plb0_acr, addr);
599
600 /* Segment1 */
601 addr = (mfdcr(plb1_acr) & ~plb1_acr_ppm_mask) | plb1_acr_ppm_fair;
602 addr = (addr & ~plb1_acr_hbu_mask) | plb1_acr_hbu_enabled;
603 addr = (addr & ~plb1_acr_rdp_mask) | plb1_acr_rdp_4deep;
604 addr = (addr & ~plb1_acr_wrp_mask) | plb1_acr_wrp_2deep;
605 mtdcr(plb1_acr, addr);
606
607 return 1;
608}
Stefan Roese54ef7fd2007-06-25 15:57:39 +0200609#endif /* defined(CONFIG_PCI) */
Stefan Roese9eba0c82006-06-02 16:18:04 +0200610
611/*************************************************************************
612 * pci_target_init
613 *
614 * The bootstrap configuration provides default settings for the pci
615 * inbound map (PIM). But the bootstrap config choices are limited and
616 * may not be sufficient for a given board.
617 *
618 ************************************************************************/
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200619#if defined(CONFIG_PCI) && defined(CONFIG_SYS_PCI_TARGET_INIT)
Stefan Roese9eba0c82006-06-02 16:18:04 +0200620void pci_target_init(struct pci_controller *hose)
621{
622 /*--------------------------------------------------------------------------+
623 * Set up Direct MMIO registers
624 *--------------------------------------------------------------------------*/
625 /*--------------------------------------------------------------------------+
626 | PowerPC440 EP PCI Master configuration.
627 | Map one 1Gig range of PLB/processor addresses to PCI memory space.
628 | PLB address 0xA0000000-0xDFFFFFFF ==> PCI address 0xA0000000-0xDFFFFFFF
629 | Use byte reversed out routines to handle endianess.
630 | Make this region non-prefetchable.
631 +--------------------------------------------------------------------------*/
632 out32r(PCIX0_PMM0MA, 0x00000000); /* PMM0 Mask/Attribute - disabled b4 setting */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200633 out32r(PCIX0_PMM0LA, CONFIG_SYS_PCI_MEMBASE); /* PMM0 Local Address */
634 out32r(PCIX0_PMM0PCILA, CONFIG_SYS_PCI_MEMBASE); /* PMM0 PCI Low Address */
Stefan Roese9eba0c82006-06-02 16:18:04 +0200635 out32r(PCIX0_PMM0PCIHA, 0x00000000); /* PMM0 PCI High Address */
636 out32r(PCIX0_PMM0MA, 0xE0000001); /* 512M + No prefetching, and enable region */
637
638 out32r(PCIX0_PMM1MA, 0x00000000); /* PMM0 Mask/Attribute - disabled b4 setting */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200639 out32r(PCIX0_PMM1LA, CONFIG_SYS_PCI_MEMBASE2); /* PMM0 Local Address */
640 out32r(PCIX0_PMM1PCILA, CONFIG_SYS_PCI_MEMBASE2); /* PMM0 PCI Low Address */
Stefan Roese9eba0c82006-06-02 16:18:04 +0200641 out32r(PCIX0_PMM1PCIHA, 0x00000000); /* PMM0 PCI High Address */
642 out32r(PCIX0_PMM1MA, 0xE0000001); /* 512M + No prefetching, and enable region */
643
644 out32r(PCIX0_PTM1MS, 0x00000001); /* Memory Size/Attribute */
645 out32r(PCIX0_PTM1LA, 0); /* Local Addr. Reg */
646 out32r(PCIX0_PTM2MS, 0); /* Memory Size/Attribute */
647 out32r(PCIX0_PTM2LA, 0); /* Local Addr. Reg */
648
649 /*--------------------------------------------------------------------------+
650 * Set up Configuration registers
651 *--------------------------------------------------------------------------*/
652
653 /* Program the board's subsystem id/vendor id */
654 pci_write_config_word(0, PCI_SUBSYSTEM_VENDOR_ID,
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200655 CONFIG_SYS_PCI_SUBSYS_VENDORID);
656 pci_write_config_word(0, PCI_SUBSYSTEM_ID, CONFIG_SYS_PCI_SUBSYS_ID);
Stefan Roese9eba0c82006-06-02 16:18:04 +0200657
658 /* Configure command register as bus master */
659 pci_write_config_word(0, PCI_COMMAND, PCI_COMMAND_MASTER);
660
661 /* 240nS PCI clock */
662 pci_write_config_word(0, PCI_LATENCY_TIMER, 1);
663
664 /* No error reporting */
665 pci_write_config_word(0, PCI_ERREN, 0);
666
667 pci_write_config_dword(0, PCI_BRDGOPT2, 0x00000101);
668
669}
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200670#endif /* defined(CONFIG_PCI) && defined(CONFIG_SYS_PCI_TARGET_INIT) */
Stefan Roese9eba0c82006-06-02 16:18:04 +0200671
672/*************************************************************************
673 * pci_master_init
674 *
675 ************************************************************************/
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200676#if defined(CONFIG_PCI) && defined(CONFIG_SYS_PCI_MASTER_INIT)
Stefan Roese9eba0c82006-06-02 16:18:04 +0200677void pci_master_init(struct pci_controller *hose)
678{
679 unsigned short temp_short;
680
681 /*--------------------------------------------------------------------------+
682 | Write the PowerPC440 EP PCI Configuration regs.
683 | Enable PowerPC440 EP to be a master on the PCI bus (PMM).
684 | Enable PowerPC440 EP to act as a PCI memory target (PTM).
685 +--------------------------------------------------------------------------*/
686 pci_read_config_word(0, PCI_COMMAND, &temp_short);
687 pci_write_config_word(0, PCI_COMMAND,
688 temp_short | PCI_COMMAND_MASTER |
689 PCI_COMMAND_MEMORY);
690}
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200691#endif /* defined(CONFIG_PCI) && defined(CONFIG_SYS_PCI_MASTER_INIT) */
Stefan Roese9eba0c82006-06-02 16:18:04 +0200692
693/*************************************************************************
694 * is_pci_host
695 *
696 * This routine is called to determine if a pci scan should be
697 * performed. With various hardware environments (especially cPCI and
698 * PPMC) it's insufficient to depend on the state of the arbiter enable
699 * bit in the strap register, or generic host/adapter assumptions.
700 *
701 * Rather than hard-code a bad assumption in the general 440 code, the
702 * 440 pci code requires the board to decide at runtime.
703 *
704 * Return 0 for adapter mode, non-zero for host (monarch) mode.
705 *
706 *
707 ************************************************************************/
708#if defined(CONFIG_PCI)
709int is_pci_host(struct pci_controller *hose)
710{
711 /* PCS440EP is always configured as host. */
712 return (1);
713}
714#endif /* defined(CONFIG_PCI) */
715
716/*************************************************************************
717 * hw_watchdog_reset
718 *
719 * This routine is called to reset (keep alive) the watchdog timer
720 *
721 ************************************************************************/
722#if defined(CONFIG_HW_WATCHDOG)
723void hw_watchdog_reset(void)
724{
725
726}
727#endif
Heiko Schocher633e03a2007-06-22 19:11:54 +0200728
729/*************************************************************************
730 * "led" Commando for the U-Boot shell
731 *
732 ************************************************************************/
733int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
734{
Heiko Schocher30b4c252007-07-11 18:39:11 +0200735 int rcode = 0, i;
Heiko Schocher633e03a2007-06-22 19:11:54 +0200736 ulong pattern = 0;
737
Heiko Schocher30b4c252007-07-11 18:39:11 +0200738 pattern = simple_strtoul (argv[1], NULL, 16);
739 if (pattern > 0x400) {
740 int val = GET_LEDS;
741 printf ("led: %x\n", val);
742 return rcode;
743 }
744 if (pattern > 0x200) {
Heiko Schocher633e03a2007-06-22 19:11:54 +0200745 status_led_blink ();
746 hang ();
747 return rcode;
748 }
Heiko Schocher30b4c252007-07-11 18:39:11 +0200749 if (pattern > 0x100) {
Heiko Schocher633e03a2007-06-22 19:11:54 +0200750 status_led_blink ();
751 return rcode;
752 }
753 pattern &= 0x0f;
Heiko Schocher30b4c252007-07-11 18:39:11 +0200754 for (i = 0; i < 4; i++) {
755 if (pattern & 0x01) status_led_set (i, STATUS_LED_ON);
756 else status_led_set (i, STATUS_LED_OFF);
757 pattern = pattern >> 1;
758 }
Heiko Schocher633e03a2007-06-22 19:11:54 +0200759 return rcode;
760}
761
762U_BOOT_CMD(
Wolfgang Denka1be4762008-05-20 16:00:29 +0200763 led, 2, 1, do_led,
Peter Tyser7467e842009-01-27 18:03:09 -0600764 "led - set the DIAG-LED\n",
Heiko Schocher30b4c252007-07-11 18:39:11 +0200765 "[bitmask] 0x01 = DIAG 1 on\n"
766 " 0x02 = DIAG 2 on\n"
767 " 0x04 = DIAG 3 on\n"
768 " 0x08 = DIAG 4 on\n"
769 " > 0x100 set the LED, who are on, to state blinking\n"
Heiko Schocher633e03a2007-06-22 19:11:54 +0200770);
771
772#if defined(CONFIG_SHA1_CHECK_UB_IMG)
773/*************************************************************************
774 * "sha1" Commando for the U-Boot shell
775 *
776 ************************************************************************/
777int do_sha1 (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
778{
779 int rcode = -1;
780
781 if (argc < 2) {
782 usage:
Peter Tyserddb3af92009-01-27 18:03:10 -0600783 cmd_usage(cmdtp);
Heiko Schocher633e03a2007-06-22 19:11:54 +0200784 return 1;
785 }
Stefan Roese9eba0c82006-06-02 16:18:04 +0200786
Heiko Schocher633e03a2007-06-22 19:11:54 +0200787 if (argc >= 3) {
788 unsigned char *data;
789 unsigned char output[20];
790 int len;
791 int i;
Wolfgang Denka0453aa2007-07-10 00:01:28 +0200792
Heiko Schocher633e03a2007-06-22 19:11:54 +0200793 data = (unsigned char *)simple_strtoul (argv[1], NULL, 16);
794 len = simple_strtoul (argv[2], NULL, 16);
795 sha1_csum (data, len, (unsigned char *)output);
796 printf ("U-Boot sum:\n");
797 for (i = 0; i < 20 ; i++) {
798 printf ("%02X ", output[i]);
799 }
800 printf ("\n");
801 if (argc == 4) {
802 data = (unsigned char *)simple_strtoul (argv[3], NULL, 16);
803 memcpy (data, output, 20);
804 }
805 return 0;
806 }
807 if (argc == 2) {
808 char *ptr = argv[1];
809 if (*ptr != '-') goto usage;
810 ptr++;
811 if ((*ptr == 'c') || (*ptr == 'C')) {
812 rcode = pcs440ep_sha1 (1);
813 printf ("SHA1 U-Boot sum %sok!\n", (rcode != 0) ? "not " : "");
814 } else if ((*ptr == 'p') || (*ptr == 'P')) {
815 rcode = pcs440ep_sha1 (2);
816 } else {
817 rcode = pcs440ep_sha1 (0);
818 }
Wolfgang Denka0453aa2007-07-10 00:01:28 +0200819 return rcode;
Heiko Schocher633e03a2007-06-22 19:11:54 +0200820 }
821 return rcode;
Stefan Roese9eba0c82006-06-02 16:18:04 +0200822}
Heiko Schocher633e03a2007-06-22 19:11:54 +0200823
824U_BOOT_CMD(
Wolfgang Denka1be4762008-05-20 16:00:29 +0200825 sha1, 4, 1, do_sha1,
826 "sha1 - calculate the SHA1 Sum\n",
Heiko Schocher633e03a2007-06-22 19:11:54 +0200827 "address len [addr] calculate the SHA1 sum [save at addr]\n"
828 " -p calculate the SHA1 sum from the U-Boot image in flash and print\n"
829 " -c check the U-Boot image in flash\n"
830);
Stefan Roese9eba0c82006-06-02 16:18:04 +0200831#endif
Heiko Schocher633e03a2007-06-22 19:11:54 +0200832
Heiko Schocher2559e0f2007-08-28 17:39:14 +0200833#if defined (CONFIG_CMD_IDE)
834/* These addresses need to be shifted one place to the left
835 * ( bus per_addr 20 -30 is connectsd on CF bus A10-A0)
836 * These values are shifted
837 */
838extern ulong *ide_bus_offset;
839void inline ide_outb(int dev, int port, unsigned char val)
840{
841 debug ("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
842 dev, port, val, (ATA_CURR_BASE(dev)+port));
843
844 out_be16((u16 *)(ATA_CURR_BASE(dev)+(port << 1)), val);
845}
846unsigned char inline ide_inb(int dev, int port)
847{
848 uchar val;
849 val = in_be16((u16 *)(ATA_CURR_BASE(dev)+(port << 1)));
850 debug ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n",
851 dev, port, (ATA_CURR_BASE(dev)+port), val);
852 return (val);
853}
854#endif
855
Heiko Schocher633e03a2007-06-22 19:11:54 +0200856#ifdef CONFIG_IDE_PREINIT
857int ide_preinit (void)
858{
859 /* Set True IDE Mode */
860 out32 (GPIO0_OR, (in32 (GPIO0_OR) | 0x00100000));
861 out32 (GPIO0_OR, (in32 (GPIO0_OR) | 0x00200000));
862 out32 (GPIO1_OR, (in32 (GPIO1_OR) & ~0x00008040));
863 udelay (100000);
864 return 0;
865}
866#endif
867
Wolfgang Denk56cbd022007-08-12 14:27:39 +0200868#if defined (CONFIG_CMD_IDE) && defined (CONFIG_IDE_RESET)
Heiko Schocher633e03a2007-06-22 19:11:54 +0200869void ide_set_reset (int idereset)
870{
871 debug ("ide_reset(%d)\n", idereset);
872 if (idereset == 0) {
873 out32 (GPIO0_OR, (in32 (GPIO0_OR) | 0x00200000));
874 } else {
875 out32 (GPIO0_OR, (in32 (GPIO0_OR) & ~0x00200000));
876 }
877 udelay (10000);
878}
Wolfgang Denk56cbd022007-08-12 14:27:39 +0200879#endif /* defined (CONFIG_CMD_IDE) && defined (CONFIG_IDE_RESET) */