]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/esd/cpci405/cpci405.c
Merge with git://www.denx.de/git/u-boot.git
[karo-tx-uboot.git] / board / esd / cpci405 / cpci405.c
1 /*
2  * (C) Copyright 2001-2003
3  * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
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 <asm/processor.h>
26 #include <asm/io.h>
27 #include <command.h>
28 #include <malloc.h>
29 #include <net.h>
30 #include <pci.h>
31
32 DECLARE_GLOBAL_DATA_PTR;
33
34 extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);       /*cmd_boot.c*/
35 #if 0
36 #define FPGA_DEBUG
37 #endif
38
39 /* fpga configuration data - generated by bin2cc */
40 const unsigned char fpgadata[] =
41 {
42 #ifdef CONFIG_CPCI405_VER2
43 # ifdef CONFIG_CPCI405AB
44 #  include "fpgadata_cpci405ab.c"
45 # else
46 #  include "fpgadata_cpci4052.c"
47 # endif
48 #else
49 # include "fpgadata_cpci405.c"
50 #endif
51 };
52
53 /*
54  * include common fpga code (for esd boards)
55  */
56 #include "../common/fpga.c"
57
58
59 #include "../common/auto_update.h"
60
61 #ifdef CONFIG_CPCI405AB
62 au_image_t au_image[] = {
63         {"cpci405ab/preinst.img", 0, -1, AU_SCRIPT},
64         {"cpci405ab/pImage", 0xffc00000, 0x000c0000, AU_NOR},
65         {"cpci405ab/pImage.initrd", 0xffcc0000, 0x00300000, AU_NOR},
66         {"cpci405ab/u-boot.img", 0xfffc0000, 0x00040000, AU_FIRMWARE},
67         {"cpci405ab/postinst.img", 0, 0, AU_SCRIPT},
68 };
69 #else
70 #ifdef CONFIG_CPCI405_VER2
71 au_image_t au_image[] = {
72         {"cpci4052/preinst.img", 0, -1, AU_SCRIPT},
73         {"cpci4052/pImage", 0xffc00000, 0x000c0000, AU_NOR},
74         {"cpci4052/pImage.initrd", 0xffcc0000, 0x00300000, AU_NOR},
75         {"cpci4052/u-boot.img", 0xfffc0000, 0x00040000, AU_FIRMWARE},
76         {"cpci4052/postinst.img", 0, 0, AU_SCRIPT},
77 };
78 #else
79 au_image_t au_image[] = {
80         {"cpci405/preinst.img", 0, -1, AU_SCRIPT},
81         {"cpci405/pImage", 0xffc00000, 0x000c0000, AU_NOR},
82         {"cpci405/pImage.initrd", 0xffcc0000, 0x00310000, AU_NOR},
83         {"cpci405/u-boot.img", 0xfffd0000, 0x00030000, AU_FIRMWARE},
84         {"cpci405/postinst.img", 0, 0, AU_SCRIPT},
85 };
86 #endif
87 #endif
88
89 int N_AU_IMAGES = (sizeof(au_image) / sizeof(au_image[0]));
90
91
92 /* Prototypes */
93 int cpci405_version(void);
94 int gunzip(void *, int, unsigned char *, unsigned long *);
95 void lxt971_no_sleep(void);
96
97
98 int board_early_init_f (void)
99 {
100 #ifndef CONFIG_CPCI405_VER2
101         int index, len, i;
102         int status;
103 #endif
104
105 #ifdef FPGA_DEBUG
106         /* set up serial port with default baudrate */
107         (void) get_clocks ();
108         gd->baudrate = CONFIG_BAUDRATE;
109         serial_init ();
110         console_init_f();
111 #endif
112
113         /*
114          * First pull fpga-prg pin low, to disable fpga logic (on version 2 board)
115          */
116         out32(GPIO0_ODR, 0x00000000);        /* no open drain pins      */
117         out32(GPIO0_TCR, CFG_FPGA_PRG);      /* setup for output        */
118         out32(GPIO0_OR,  CFG_FPGA_PRG);      /* set output pins to high */
119         out32(GPIO0_OR, 0);                  /* pull prg low            */
120
121         /*
122          * Boot onboard FPGA
123          */
124 #ifndef CONFIG_CPCI405_VER2
125         if (cpci405_version() == 1) {
126                 status = fpga_boot((unsigned char *)fpgadata, sizeof(fpgadata));
127                 if (status != 0) {
128                         /* booting FPGA failed */
129 #ifndef FPGA_DEBUG
130                         /* set up serial port with default baudrate */
131                         (void) get_clocks ();
132                         gd->baudrate = CONFIG_BAUDRATE;
133                         serial_init ();
134                         console_init_f();
135 #endif
136                         printf("\nFPGA: Booting failed ");
137                         switch (status) {
138                         case ERROR_FPGA_PRG_INIT_LOW:
139                                 printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
140                                 break;
141                         case ERROR_FPGA_PRG_INIT_HIGH:
142                                 printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
143                                 break;
144                         case ERROR_FPGA_PRG_DONE:
145                                 printf("(Timeout: DONE not high after programming FPGA)\n ");
146                                 break;
147                         }
148
149                         /* display infos on fpgaimage */
150                         index = 15;
151                         for (i=0; i<4; i++) {
152                                 len = fpgadata[index];
153                                 printf("FPGA: %s\n", &(fpgadata[index+1]));
154                                 index += len+3;
155                         }
156                         putc ('\n');
157                         /* delayed reboot */
158                         for (i=20; i>0; i--) {
159                                 printf("Rebooting in %2d seconds \r",i);
160                                 for (index=0;index<1000;index++)
161                                         udelay(1000);
162                         }
163                         putc ('\n');
164                         do_reset(NULL, 0, 0, NULL);
165                 }
166         }
167 #endif /* !CONFIG_CPCI405_VER2 */
168
169         /*
170          * IRQ 0-15  405GP internally generated; active high; level sensitive
171          * IRQ 16    405GP internally generated; active low; level sensitive
172          * IRQ 17-24 RESERVED
173          * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
174          * IRQ 26 (EXT IRQ 1) CAN1 (+FPGA on CPCI4052) ; active low; level sensitive
175          * IRQ 27 (EXT IRQ 2) PCI SLOT 0; active low; level sensitive
176          * IRQ 28 (EXT IRQ 3) PCI SLOT 1; active low; level sensitive
177          * IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
178          * IRQ 30 (EXT IRQ 5) PCI SLOT 3; active low; level sensitive
179          * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive
180          */
181         mtdcr(uicsr, 0xFFFFFFFF);       /* clear all ints */
182         mtdcr(uicer, 0x00000000);       /* disable all ints */
183         mtdcr(uiccr, 0x00000000);       /* set all to be non-critical*/
184 #ifdef CONFIG_CPCI405_6U
185         if (cpci405_version() == 3) {
186                 mtdcr(uicpr, 0xFFFFFF99);       /* set int polarities */
187         } else {
188                 mtdcr(uicpr, 0xFFFFFF81);       /* set int polarities */
189         }
190 #else
191         mtdcr(uicpr, 0xFFFFFF81);       /* set int polarities */
192 #endif
193         mtdcr(uictr, 0x10000000);       /* set int trigger levels */
194         mtdcr(uicvcr, 0x00000001);      /* set vect base=0,INT0 highest priority*/
195         mtdcr(uicsr, 0xFFFFFFFF);       /* clear all ints */
196
197         return 0;
198 }
199
200
201 /* ------------------------------------------------------------------------- */
202
203 int ctermm2(void)
204 {
205 #ifdef CONFIG_CPCI405_VER2
206         return 0;                       /* no, board is cpci405 */
207 #else
208         if ((*(unsigned char *)0xf0000400 == 0x00) &&
209             (*(unsigned char *)0xf0000401 == 0x01))
210                 return 0;               /* no, board is cpci405 */
211         else
212                 return -1;              /* yes, board is cterm-m2 */
213 #endif
214 }
215
216
217 int cpci405_host(void)
218 {
219         if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
220                 return -1;              /* yes, board is cpci405 host */
221         else
222                 return 0;               /* no, board is cpci405 adapter */
223 }
224
225
226 int cpci405_version(void)
227 {
228         unsigned long cntrl0Reg;
229         unsigned long value;
230
231         /*
232          * Setup GPIO pins (CS2/GPIO11 and CS3/GPIO12 as GPIO)
233          */
234         cntrl0Reg = mfdcr(cntrl0);
235         mtdcr(cntrl0, cntrl0Reg | 0x03000000);
236         out_be32((void*)GPIO0_ODR, in_be32((void*)GPIO0_ODR) & ~0x00180000);
237         out_be32((void*)GPIO0_TCR, in_be32((void*)GPIO0_TCR) & ~0x00180000);
238         udelay(1000);                   /* wait some time before reading input */
239         value = in_be32((void*)GPIO0_IR) & 0x00180000;       /* get config bits */
240
241         /*
242          * Restore GPIO settings
243          */
244         mtdcr(cntrl0, cntrl0Reg);
245
246         switch (value) {
247         case 0x00180000:
248                 /* CS2==1 && CS3==1 -> version 1 */
249                 return 1;
250         case 0x00080000:
251                 /* CS2==0 && CS3==1 -> version 2 */
252                 return 2;
253         case 0x00100000:
254                 /* CS2==1 && CS3==0 -> version 3 or 6U board */
255                 return 3;
256         case 0x00000000:
257                 /* CS2==0 && CS3==0 -> version 4 */
258                 return 4;
259         default:
260                 /* should not be reached! */
261                 return 2;
262         }
263 }
264
265
266 int misc_init_f (void)
267 {
268         return 0;  /* dummy implementation */
269 }
270
271
272 int misc_init_r (void)
273 {
274         unsigned long cntrl0Reg;
275
276         /* adjust flash start and offset */
277         gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
278         gd->bd->bi_flashoffset = 0;
279
280 #ifdef CONFIG_CPCI405_VER2
281         {
282         unsigned char *dst;
283         ulong len = sizeof(fpgadata);
284         int status;
285         int index;
286         int i;
287
288         /*
289          * On CPCI-405 version 2 the environment is saved in eeprom!
290          * FPGA can be gzip compressed (malloc) and booted this late.
291          */
292         if (cpci405_version() >= 2) {
293                 /*
294                  * Setup GPIO pins (CS6+CS7 as GPIO)
295                  */
296                 cntrl0Reg = mfdcr(cntrl0);
297                 mtdcr(cntrl0, cntrl0Reg | 0x00300000);
298
299                 dst = malloc(CFG_FPGA_MAX_SIZE);
300                 if (gunzip (dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, &len) != 0) {
301                         printf ("GUNZIP ERROR - must RESET board to recover\n");
302                         do_reset (NULL, 0, 0, NULL);
303                 }
304
305                 status = fpga_boot(dst, len);
306                 if (status != 0) {
307                         printf("\nFPGA: Booting failed ");
308                         switch (status) {
309                         case ERROR_FPGA_PRG_INIT_LOW:
310                                 printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
311                                 break;
312                         case ERROR_FPGA_PRG_INIT_HIGH:
313                                 printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
314                                 break;
315                         case ERROR_FPGA_PRG_DONE:
316                                 printf("(Timeout: DONE not high after programming FPGA)\n ");
317                                 break;
318                         }
319
320                         /* display infos on fpgaimage */
321                         index = 15;
322                         for (i=0; i<4; i++) {
323                                 len = dst[index];
324                                 printf("FPGA: %s\n", &(dst[index+1]));
325                                 index += len+3;
326                         }
327                         putc ('\n');
328                         /* delayed reboot */
329                         for (i=20; i>0; i--) {
330                                 printf("Rebooting in %2d seconds \r",i);
331                                 for (index=0;index<1000;index++)
332                                         udelay(1000);
333                         }
334                         putc ('\n');
335                         do_reset(NULL, 0, 0, NULL);
336                 }
337
338                 /* restore gpio/cs settings */
339                 mtdcr(cntrl0, cntrl0Reg);
340
341                 puts("FPGA:  ");
342
343                 /* display infos on fpgaimage */
344                 index = 15;
345                 for (i=0; i<4; i++) {
346                         len = dst[index];
347                         printf("%s ", &(dst[index+1]));
348                         index += len+3;
349                 }
350                 putc ('\n');
351
352                 free(dst);
353
354                 /*
355                  * Reset FPGA via FPGA_DATA pin
356                  */
357                 SET_FPGA(FPGA_PRG | FPGA_CLK);
358                 udelay(1000); /* wait 1ms */
359                 SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
360                 udelay(1000); /* wait 1ms */
361
362 #ifdef CONFIG_CPCI405_6U
363                 if (cpci405_version() == 3) {
364                         volatile unsigned short *fpga_mode = (unsigned short *)CFG_FPGA_BASE_ADDR;
365                         volatile unsigned char *leds = (unsigned char *)CFG_LED_ADDR;
366
367                         /*
368                          * Enable outputs in fpga on version 3 board
369                          */
370                         *fpga_mode |= CFG_FPGA_MODE_ENABLE_OUTPUT;
371
372                         /*
373                          * Set outputs to 0
374                          */
375                         *leds = 0x00;
376
377                         /*
378                          * Reset external DUART
379                          */
380                         *fpga_mode |= CFG_FPGA_MODE_DUART_RESET;
381                         udelay(100);
382                         *fpga_mode &= ~(CFG_FPGA_MODE_DUART_RESET);
383                 }
384 #endif
385         }
386         else {
387                 puts("\n*** U-Boot Version does not match Board Version!\n");
388                 puts("*** CPCI-405 Version 1.x detected!\n");
389                 puts("*** Please use correct U-Boot version (CPCI405 instead of CPCI4052)!\n\n");
390         }
391         }
392
393 #else /* CONFIG_CPCI405_VER2 */
394
395 #if 0 /* test-only: code-plug now not relavant for ip-address any more */
396         /*
397          * Generate last byte of ip-addr from code-plug @ 0xf0000400
398          */
399         if (ctermm2()) {
400                 char str[32];
401                 unsigned char ipbyte = *(unsigned char *)0xf0000400;
402
403                 /*
404                  * Only overwrite ip-addr with allowed values
405                  */
406                 if ((ipbyte != 0x00) && (ipbyte != 0xff)) {
407                         bd->bi_ip_addr = (bd->bi_ip_addr & 0xffffff00) | ipbyte;
408                         sprintf(str, "%ld.%ld.%ld.%ld",
409                                 (bd->bi_ip_addr & 0xff000000) >> 24,
410                                 (bd->bi_ip_addr & 0x00ff0000) >> 16,
411                                 (bd->bi_ip_addr & 0x0000ff00) >> 8,
412                                 (bd->bi_ip_addr & 0x000000ff));
413                         setenv("ipaddr", str);
414                 }
415         }
416 #endif
417
418         if (cpci405_version() >= 2) {
419                 puts("\n*** U-Boot Version does not match Board Version!\n");
420                 puts("*** CPCI-405 Board Version 2.x detected!\n");
421                 puts("*** Please use correct U-Boot version (CPCI4052 instead of CPCI405)!\n\n");
422         }
423
424 #endif /* CONFIG_CPCI405_VER2 */
425
426         /*
427          * Select cts (and not dsr) on uart1
428          */
429         cntrl0Reg = mfdcr(cntrl0);
430         mtdcr(cntrl0, cntrl0Reg | 0x00001000);
431
432         return (0);
433 }
434
435
436 /*
437  * Check Board Identity:
438  */
439
440 int checkboard (void)
441 {
442 #ifndef CONFIG_CPCI405_VER2
443         int index;
444         int len;
445 #endif
446         char str[64];
447         int i = getenv_r ("serial#", str, sizeof(str));
448         unsigned short ver;
449
450         puts ("Board: ");
451
452         if (i == -1) {
453                 puts ("### No HW ID - assuming CPCI405");
454         } else {
455                 puts(str);
456         }
457
458         ver = cpci405_version();
459         printf(" (Ver %d.x, ", ver);
460
461 #if 0 /* test-only */
462         if (ver >= 2) {
463                 volatile u16 *fpga_status = (u16 *)CFG_FPGA_BASE_ADDR + 1;
464
465                 if (*fpga_status & CFG_FPGA_STATUS_FLASH) {
466                         puts ("FLASH Bank B, ");
467                 } else {
468                         puts ("FLASH Bank A, ");
469                 }
470         }
471 #endif
472
473         if (ctermm2()) {
474                 char str[4];
475
476                 /*
477                  * Read board-id and save in env-variable
478                  */
479                 sprintf(str, "%d", *(unsigned char *)0xf0000400);
480                 setenv("boardid", str);
481                 printf("CTERM-M2 - Id=%s)", str);
482         } else {
483                 if (cpci405_host()) {
484                         puts ("PCI Host Version)");
485                 } else {
486                         puts ("PCI Adapter Version)");
487                 }
488         }
489
490 #ifndef CONFIG_CPCI405_VER2
491         puts ("\nFPGA:  ");
492
493         /* display infos on fpgaimage */
494         index = 15;
495         for (i=0; i<4; i++) {
496                 len = fpgadata[index];
497                 printf("%s ", &(fpgadata[index+1]));
498                 index += len+3;
499         }
500 #endif
501
502         putc ('\n');
503         return 0;
504 }
505
506 /* ------------------------------------------------------------------------- */
507
508 long int initdram (int board_type)
509 {
510         unsigned long val;
511
512         mtdcr(memcfga, mem_mb0cf);
513         val = mfdcr(memcfgd);
514
515         return (4*1024*1024 << ((val & 0x000e0000) >> 17));
516 }
517
518
519 void reset_phy(void)
520 {
521 #ifdef CONFIG_LXT971_NO_SLEEP
522
523         /*
524          * Disable sleep mode in LXT971
525          */
526         lxt971_no_sleep();
527 #endif
528 }
529
530
531 /* ------------------------------------------------------------------------- */
532
533 #ifdef CONFIG_CPCI405_VER2
534 #ifdef CONFIG_IDE_RESET
535
536 void ide_set_reset(int on)
537 {
538         volatile unsigned short *fpga_mode = (unsigned short *)CFG_FPGA_BASE_ADDR;
539
540         /*
541          * Assert or deassert CompactFlash Reset Pin
542          */
543         if (on) {               /* assert RESET */
544                 *fpga_mode &= ~(CFG_FPGA_MODE_CF_RESET);
545         } else {                /* release RESET */
546                 *fpga_mode |= CFG_FPGA_MODE_CF_RESET;
547         }
548 }
549
550 #endif /* CONFIG_IDE_RESET */
551 #endif /* CONFIG_CPCI405_VER2 */
552
553
554 #if defined(CONFIG_PCI)
555 void cpci405_pci_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
556 {
557         unsigned char int_line = 0xff;
558
559         /*
560          * Write pci interrupt line register (cpci405 specific)
561          */
562         switch (PCI_DEV(dev) & 0x03) {
563         case 0:
564                 int_line = 27 + 2;
565                 break;
566         case 1:
567                 int_line = 27 + 3;
568                 break;
569         case 2:
570                 int_line = 27 + 0;
571                 break;
572         case 3:
573                 int_line = 27 + 1;
574                 break;
575         }
576
577         pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, int_line);
578 }
579
580 int pci_pre_init(struct pci_controller *hose)
581 {
582         hose->fixup_irq = cpci405_pci_fixup_irq;
583         return 1;
584 }
585 #endif /* defined(CONFIG_PCI) */
586
587
588
589 #ifdef CONFIG_CPCI405AB
590
591 #define ONE_WIRE_CLEAR   (*(volatile unsigned short *)(CFG_FPGA_BASE_ADDR + CFG_FPGA_MODE) \
592                           |= CFG_FPGA_MODE_1WIRE_DIR)
593 #define ONE_WIRE_SET     (*(volatile unsigned short *)(CFG_FPGA_BASE_ADDR + CFG_FPGA_MODE) \
594                           &= ~CFG_FPGA_MODE_1WIRE_DIR)
595 #define ONE_WIRE_GET     (*(volatile unsigned short *)(CFG_FPGA_BASE_ADDR + CFG_FPGA_STATUS) \
596                           & CFG_FPGA_MODE_1WIRE)
597
598 /*
599  * Generate a 1-wire reset, return 1 if no presence detect was found,
600  * return 0 otherwise.
601  * (NOTE: Does not handle alarm presence from DS2404/DS1994)
602  */
603 int OWTouchReset(void)
604 {
605         int result;
606
607         ONE_WIRE_CLEAR;
608         udelay(480);
609         ONE_WIRE_SET;
610         udelay(70);
611
612         result = ONE_WIRE_GET;
613
614         udelay(410);
615         return result;
616 }
617
618
619 /*
620  * Send 1 a 1-wire write bit.
621  * Provide 10us recovery time.
622  */
623 void OWWriteBit(int bit)
624 {
625         if (bit) {
626                 /*
627                  * write '1' bit
628                  */
629                 ONE_WIRE_CLEAR;
630                 udelay(6);
631                 ONE_WIRE_SET;
632                 udelay(64);
633         } else {
634                 /*
635                  * write '0' bit
636                  */
637                 ONE_WIRE_CLEAR;
638                 udelay(60);
639                 ONE_WIRE_SET;
640                 udelay(10);
641         }
642 }
643
644
645 /*
646  * Read a bit from the 1-wire bus and return it.
647  * Provide 10us recovery time.
648  */
649 int OWReadBit(void)
650 {
651         int result;
652
653         ONE_WIRE_CLEAR;
654         udelay(6);
655         ONE_WIRE_SET;
656         udelay(9);
657
658         result = ONE_WIRE_GET;
659
660         udelay(55);
661         return result;
662 }
663
664
665 void OWWriteByte(int data)
666 {
667         int loop;
668
669         for (loop=0; loop<8; loop++) {
670                 OWWriteBit(data & 0x01);
671                 data >>= 1;
672         }
673 }
674
675
676 int OWReadByte(void)
677 {
678         int loop, result = 0;
679
680         for (loop=0; loop<8; loop++) {
681                 result >>= 1;
682                 if (OWReadBit()) {
683                         result |= 0x80;
684                 }
685         }
686
687         return result;
688 }
689
690
691 int do_onewire(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
692 {
693         volatile unsigned short val;
694         int result;
695         int i;
696         unsigned char ow_id[6];
697         char str[32];
698         unsigned char ow_crc;
699
700         /*
701          * Clear 1-wire bit (open drain with pull-up)
702          */
703         val = *(volatile unsigned short *)0xf0400000;
704         val &= ~0x1000; /* clear 1-wire bit */
705         *(volatile unsigned short *)0xf0400000 = val;
706
707         result = OWTouchReset();
708         if (result != 0) {
709                 puts("No 1-wire device detected!\n");
710         }
711
712         OWWriteByte(0x33); /* send read rom command */
713         OWReadByte(); /* skip family code ( == 0x01) */
714         for (i=0; i<6; i++) {
715                 ow_id[i] = OWReadByte();
716         }
717         ow_crc = OWReadByte(); /* read crc */
718
719         sprintf(str, "%08X%04X", *(unsigned int *)&ow_id[0], *(unsigned short *)&ow_id[4]);
720         printf("Setting environment variable 'ow_id' to %s\n", str);
721         setenv("ow_id", str);
722
723         return 0;
724 }
725 U_BOOT_CMD(
726         onewire,        1,      1,      do_onewire,
727         "onewire - Read 1-write ID\n",
728         NULL
729         );
730
731
732 #define CFG_I2C_EEPROM_ADDR_2   0x51    /* EEPROM CAT28WC32             */
733 #define CFG_ENV_SIZE_2  0x800   /* 2048 bytes may be used for env vars*/
734
735 /*
736  * Write backplane ip-address...
737  */
738 int do_get_bpip(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
739 {
740         bd_t *bd = gd->bd;
741         char *buf;
742         ulong crc;
743         char str[32];
744         char *ptr;
745         IPaddr_t ipaddr;
746
747         buf = malloc(CFG_ENV_SIZE_2);
748         if (eeprom_read(CFG_I2C_EEPROM_ADDR_2, 0, (uchar *)buf, CFG_ENV_SIZE_2)) {
749                 puts("\nError reading backplane EEPROM!\n");
750         } else {
751                 crc = crc32(0, (uchar *)(buf+4), CFG_ENV_SIZE_2-4);
752                 if (crc != *(ulong *)buf) {
753                         printf("ERROR: crc mismatch %08lx %08lx\n", crc, *(ulong *)buf);
754                         return -1;
755                 }
756
757                 /*
758                  * Find bp_ip
759                  */
760                 ptr = strstr(buf+4, "bp_ip=");
761                 if (ptr == NULL) {
762                         printf("ERROR: bp_ip not found!\n");
763                         return -1;
764                 }
765                 ptr += 6;
766                 ipaddr = string_to_ip(ptr);
767
768                 /*
769                  * Update whole ip-addr
770                  */
771                 bd->bi_ip_addr = ipaddr;
772                 sprintf(str, "%ld.%ld.%ld.%ld",
773                         (bd->bi_ip_addr & 0xff000000) >> 24,
774                         (bd->bi_ip_addr & 0x00ff0000) >> 16,
775                         (bd->bi_ip_addr & 0x0000ff00) >> 8,
776                         (bd->bi_ip_addr & 0x000000ff));
777                 setenv("ipaddr", str);
778                 printf("Updated ip_addr from bp_eeprom to %s!\n", str);
779         }
780
781         free(buf);
782
783         return 0;
784 }
785 U_BOOT_CMD(
786         getbpip,        1,      1,      do_get_bpip,
787         "getbpip - Update IP-Address with Backplane IP-Address\n",
788         NULL
789         );
790
791 /*
792  * Set and print backplane ip...
793  */
794 int do_set_bpip(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
795 {
796         char *buf;
797         char str[32];
798         ulong crc;
799
800         if (argc < 2) {
801                 puts("ERROR!\n");
802                 return -1;
803         }
804
805         printf("Setting bp_ip to %s\n", argv[1]);
806         buf = malloc(CFG_ENV_SIZE_2);
807         memset(buf, 0, CFG_ENV_SIZE_2);
808         sprintf(str, "bp_ip=%s", argv[1]);
809         strcpy(buf+4, str);
810         crc = crc32(0, (uchar *)(buf+4), CFG_ENV_SIZE_2-4);
811         *(ulong *)buf = crc;
812
813         if (eeprom_write(CFG_I2C_EEPROM_ADDR_2, 0, (uchar *)buf, CFG_ENV_SIZE_2)) {
814                 puts("\nError writing backplane EEPROM!\n");
815         }
816
817         free(buf);
818
819         return 0;
820 }
821 U_BOOT_CMD(
822         setbpip,        2,      1,      do_set_bpip,
823         "setbpip - Write Backplane IP-Address\n",
824         NULL
825         );
826
827 #endif /* CONFIG_CPCI405AB */