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