uboot/board/hermes/hermes.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000
   3 * Wolfgang Denk, DENX Software Engineering, wd@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 <commproc.h>
  26#include <mpc8xx.h>
  27
  28#ifdef CONFIG_SHOW_BOOT_PROGRESS
  29# include <status_led.h>
  30# define SHOW_BOOT_PROGRESS(arg)        show_boot_progress(arg)
  31#else
  32# define SHOW_BOOT_PROGRESS(arg)
  33#endif
  34
  35DECLARE_GLOBAL_DATA_PTR;
  36
  37/* ------------------------------------------------------------------------- */
  38
  39static long int dram_size (long int, long int *, long int);
  40static ulong board_init (void);
  41static void send_smi_frame (volatile scc_t * sp, volatile cbd_t * bd,
  42                                                        uchar * msg);
  43
  44/* ------------------------------------------------------------------------- */
  45
  46#define _NOT_USED_      0xFFFFFFFF
  47
  48const uint sdram_table[] = {
  49        /*
  50         * Single Read. (Offset 0 in UPMA RAM)
  51         */
  52        0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
  53        0x1ff77c47,                                     /* last */
  54        /*
  55         * SDRAM Initialization (offset 5 in UPMA RAM)
  56         *
  57         * This is no UPM entry point. The following definition uses
  58         * the remaining space to establish an initialization
  59         * sequence, which is executed by a RUN command.
  60         *
  61         */
  62        0x1fe77c35, 0xffaffc34, 0x1fa57c35,     /* last */
  63        /*
  64         * Burst Read. (Offset 8 in UPMA RAM)
  65         */
  66        0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
  67        0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47, /* last */
  68        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  69        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  70        /*
  71         * Single Write. (Offset 18 in UPMA RAM)
  72         */
  73        0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47, /* last */
  74        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  75        /*
  76         * Burst Write. (Offset 20 in UPMA RAM)
  77         */
  78        0x1f07fc04, 0xeeaebc00, 0x10ad4c00, 0xf0afcc00,
  79        0xf0afcc00, 0xe1bb8c06, 0x1ff77c47,     /* last */
  80        _NOT_USED_,
  81        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  82        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  83        /*
  84         * Refresh  (Offset 30 in UPMA RAM)
  85         */
  86        0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
  87        0xfffffc84, 0xfffffc07,         /* last */
  88        _NOT_USED_, _NOT_USED_,
  89        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  90        /*
  91         * Exception. (Offset 3c in UPMA RAM)
  92         */
  93        0x7ffffc07,                                     /* last */
  94        _NOT_USED_, _NOT_USED_, _NOT_USED_,
  95};
  96
  97/* ------------------------------------------------------------------------- */
  98
  99
 100/*
 101 * Check Board Identity:
 102 *
 103 * Test ID string (HERMES...)
 104 *
 105 * Return code for board revision and network speed
 106 */
 107
 108int checkboard (void)
 109{
 110        char *s = getenv ("serial#");
 111        char *e;
 112
 113        puts ("Board: ");
 114
 115        if (!s || strncmp (s, "HERMES", 6)) {
 116                puts ("### No HW ID - assuming HERMES-PRO");
 117        } else {
 118                for (e = s; *e; ++e) {
 119                        if (*e == ' ')
 120                                break;
 121                }
 122
 123                for (; s < e; ++s) {
 124                        putc (*s);
 125                }
 126        }
 127
 128        gd->board_type = board_init ();
 129
 130        printf ("  Rev. %ld.x\n", (gd->board_type >> 16));
 131
 132        return (0);
 133}
 134
 135/* ------------------------------------------------------------------------- */
 136
 137phys_size_t initdram (int board_type)
 138{
 139        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 140        volatile memctl8xx_t *memctl = &immap->im_memctl;
 141        long int size, size8, size9;
 142
 143        upmconfig (UPMA, (uint *) sdram_table,
 144                           sizeof (sdram_table) / sizeof (uint));
 145
 146        /*
 147         * Preliminary prescaler for refresh
 148         */
 149        memctl->memc_mptpr = 0x0400;
 150
 151        memctl->memc_mar = 0x00000088;
 152
 153        /*
 154         * Map controller banks 1 to the SDRAM banks at preliminary address
 155         */
 156        memctl->memc_or1 = CONFIG_SYS_OR1_PRELIM;
 157        memctl->memc_br1 = CONFIG_SYS_BR1_PRELIM;
 158
 159        /* HERMES-PRO boards have only one bank SDRAM */
 160
 161
 162        udelay (200);
 163
 164        /* perform SDRAM initializsation sequence */
 165
 166        memctl->memc_mamr = 0xD0802114;
 167        memctl->memc_mcr = 0x80002105;
 168        udelay (1);
 169        memctl->memc_mamr = 0xD0802118;
 170        memctl->memc_mcr = 0x80002130;
 171        udelay (1);
 172        memctl->memc_mamr = 0xD0802114;
 173        memctl->memc_mcr = 0x80002106;
 174
 175        udelay (1000);
 176
 177        /*
 178         * Check Bank 0 Memory Size for re-configuration
 179         *
 180         * try 8 column mode
 181         */
 182        size8 = dram_size (CONFIG_SYS_MAMR_8COL, (long *) SDRAM_BASE_PRELIM,
 183                                           SDRAM_MAX_SIZE);
 184
 185        udelay (1000);
 186
 187        /*
 188         * try 9 column mode
 189         */
 190        size9 = dram_size (CONFIG_SYS_MAMR_9COL, (long *) SDRAM_BASE_PRELIM,
 191                                           SDRAM_MAX_SIZE);
 192
 193        if (size8 < size9) {            /* leave configuration at 9 columns */
 194                size = size9;
 195/*      debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20);  */
 196        } else {                                        /* back to 8 columns            */
 197                size = size8;
 198                memctl->memc_mamr = CONFIG_SYS_MAMR_8COL;
 199                udelay (500);
 200/*      debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20);  */
 201        }
 202
 203        udelay (1000);
 204
 205        memctl->memc_or1 = ((-size) & 0xFFFF0000) | SDRAM_TIMING;
 206        memctl->memc_br1 = (CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
 207
 208        udelay (10000);
 209
 210        return (size);
 211}
 212
 213/* ------------------------------------------------------------------------- */
 214
 215/*
 216 * Check memory range for valid RAM. A simple memory test determines
 217 * the actually available RAM size between addresses `base' and
 218 * `base + maxsize'. Some (not all) hardware errors are detected:
 219 * - short between address lines
 220 * - short between data lines
 221 */
 222
 223static long int dram_size (long int mamr_value, long int *base,
 224                                                   long int maxsize)
 225{
 226        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 227        volatile memctl8xx_t *memctl = &immap->im_memctl;
 228
 229        memctl->memc_mamr = mamr_value;
 230
 231        return (get_ram_size(base, maxsize));
 232}
 233
 234/* ------------------------------------------------------------------------- */
 235
 236#define PB_LED_3        0x00020000      /* Status LED's */
 237#define PB_LED_2        0x00010000
 238#define PB_LED_1        0x00008000
 239#define PB_LED_0        0x00004000
 240
 241#define PB_LED_ALL      (PB_LED_0 | PB_LED_1 | PB_LED_2 | PB_LED_3)
 242
 243#define PC_REP_SPD1     0x00000800
 244#define PC_REP_SPD0     0x00000400
 245
 246#define PB_RESET_2081   0x00000020      /* Reset PEB2081 */
 247
 248#define PB_MAI_4        0x00000010      /* Configuration */
 249#define PB_MAI_3        0x00000008
 250#define PB_MAI_2        0x00000004
 251#define PB_MAI_1        0x00000002
 252#define PB_MAI_0        0x00000001
 253
 254#define PB_MAI_ALL      (PB_MAI_0 | PB_MAI_1 | PB_MAI_2 | PB_MAI_3 | PB_MAI_4)
 255
 256
 257#define PC_REP_MGRPRS   0x0200
 258#define PC_REP_SPD      0x0040          /* Select 100 Mbps */
 259#define PC_REP_RES      0x0004
 260#define PC_BIT14        0x0002          /* ??? */
 261#define PC_BIT15        0x0001          /* ??? ENDSL ?? */
 262
 263/* ------------------------------------------------------------------------- */
 264
 265static ulong board_init (void)
 266{
 267        volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
 268        ulong reg, revision, speed = 100;
 269        int ethspeed;
 270        char *s;
 271
 272        if ((s = getenv ("ethspeed")) != NULL) {
 273                if (strcmp (s, "100") == 0) {
 274                        ethspeed = 100;
 275                } else if (strcmp (s, "10") == 0) {
 276                        ethspeed = 10;
 277                } else {
 278                        ethspeed = 0;
 279                }
 280        } else {
 281                ethspeed = 0;
 282        }
 283
 284        /* Configure Port B Output Pins => 0x0003cc3F */
 285        reg = PB_LED_ALL | PC_REP_SPD1 | PC_REP_SPD0 | PB_RESET_2081 |
 286                        PB_MAI_ALL;
 287        immr->im_cpm.cp_pbpar &= ~reg;
 288        immr->im_cpm.cp_pbodr &= ~reg;
 289        immr->im_cpm.cp_pbdat &= ~reg;  /* all 0 */
 290        immr->im_cpm.cp_pbdir |= reg;
 291
 292        /* Check hardware revision */
 293        if ((immr->im_ioport.iop_pcdat & 0x0003) == 0x0003) {
 294                /*
 295                 * Revision 3.x hardware
 296                 */
 297                revision = 3;
 298
 299                immr->im_ioport.iop_pcdat = 0x0240;
 300                immr->im_ioport.iop_pcdir = (PC_REP_MGRPRS | PC_REP_SPD | PC_REP_RES | PC_BIT14);       /* = 0x0246 */
 301                immr->im_ioport.iop_pcdat |= PC_REP_RES;
 302        } else {
 303                immr->im_ioport.iop_pcdat = 0x0002;
 304                immr->im_ioport.iop_pcdir = (PC_REP_MGRPRS | PC_REP_RES | PC_BIT14 | PC_BIT15); /* = 0x0207 */
 305
 306                if ((immr->im_ioport.iop_pcdat & PC_REP_SPD) == 0) {
 307                        /*
 308                         * Revision 2.x hardware: PC9 connected to PB21
 309                         */
 310                        revision = 2;
 311
 312                        if (ethspeed == 0) {
 313                                /* both 10 and 100 Mbps allowed:
 314                                 * select 10 Mbps and autonegotiation
 315                                 */
 316                                puts ("  [10+100]");
 317                                immr->im_cpm.cp_pbdat = 0;      /* SPD1:SPD0 = 0:0 - autonegot. */
 318                                speed = 10;
 319                        } else if (ethspeed == 10) {
 320                                /* we are asked for 10 Mbps,
 321                                 * so select 10 Mbps
 322                                 */
 323                                puts ("  [10]");
 324                                immr->im_cpm.cp_pbdat = 0;      /* ??? */
 325                                speed = 10;
 326                        } else {
 327                                /* anything else:
 328                                 * select 100 Mbps
 329                                 */
 330                                puts ("  [100]");
 331                                immr->im_cpm.cp_pbdat = PC_REP_SPD0 | PC_REP_SPD1;
 332                                /* SPD1:SPD0 = 1:1 - 100 Mbps */
 333                                speed = 100;
 334                        }
 335                        immr->im_ioport.iop_pcdat |= (PC_REP_RES | PC_BIT14);
 336
 337                        /* must be run from RAM  */
 338                        /* start_lxt980 (speed); */
 339                /*************************/
 340                } else {
 341                        /*
 342                         * Revision 1.x hardware
 343                         */
 344                        revision = 1;
 345
 346                        immr->im_ioport.iop_pcdat = PC_REP_MGRPRS | PC_BIT14;   /* = 0x0202 */
 347                        immr->im_ioport.iop_pcdir = (PC_REP_MGRPRS | PC_REP_SPD | PC_REP_RES | PC_BIT14 | PC_BIT15);    /* = 0x0247 */
 348
 349                        if (ethspeed == 0) {
 350                                /* both 10 and 100 Mbps allowed:
 351                                 * select 100 Mbps and autonegotiation
 352                                 */
 353                                puts ("  [10+100]");
 354                                immr->im_cpm.cp_pbdat = 0;      /* SPD1:SPD0 = 0:0 - autonegot. */
 355                                immr->im_ioport.iop_pcdat |= PC_REP_SPD;
 356                        } else if (ethspeed == 10) {
 357                                /* we are asked for 10 Mbps,
 358                                   * so select 10 Mbps
 359                                 */
 360                                puts ("  [10]");
 361                                immr->im_cpm.cp_pbdat = PC_REP_SPD0;    /* SPD1:SPD0 = 0:1 - 10 Mbps */
 362                        } else {
 363                                /* anything else:
 364                                   * select 100 Mbps
 365                                 */
 366                                puts ("  [100]");
 367                                immr->im_cpm.cp_pbdat = PC_REP_SPD0 | PC_REP_SPD1;
 368                                /* SPD1:SPD0 = 1:1 - 100 Mbps */
 369                                immr->im_ioport.iop_pcdat |= PC_REP_SPD;
 370                        }
 371
 372                        immr->im_ioport.iop_pcdat |= PC_REP_RES;
 373                }
 374        }
 375        SHOW_BOOT_PROGRESS (0x00);
 376
 377        return ((revision << 16) | (speed & 0xFFFF));
 378}
 379
 380/* ------------------------------------------------------------------------- */
 381
 382#define SCC_SM          1                       /* Index => SCC2 */
 383#define PROFF           PROFF_SCC2
 384
 385#define SMI_MSGLEN      8                       /* Length of SMI Messages        */
 386
 387#define PHYGPCR_ADDR    0x109   /* Port Enable               */
 388#define PHYPCR_ADDR     0x132           /* PHY Port Control Reg. (port 1)    */
 389#define LEDPCR_ADDR     0x141           /* LED Port Control Reg.         */
 390#define RPRESET_ADDR    0x144   /* Repeater Reset            */
 391
 392#define PHYPCR_SPEED    0x2000  /* on for 100 Mbps, off for 10 Mbps  */
 393#define PHYPCR_AN       0x1000          /* on to enable  Auto-Negotiation    */
 394#define PHYPCR_REST_AN  0x0200  /* on to restart Auto-Negotiation    */
 395#define PHYPCR_FDX      0x0100          /* on for Full Duplex, off for HDX   */
 396#define PHYPCR_COLT     0x0080          /* on to enable COL signal test      */
 397
 398/* ------------------------------------------------------------------------- */
 399
 400/*
 401 * Must run from RAM:
 402 * uses parameter RAM area which is used for stack while running from ROM
 403 */
 404void hermes_start_lxt980 (int speed)
 405{
 406        volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
 407        volatile cpm8xx_t *cp = (cpm8xx_t *) & (immr->im_cpm);
 408        volatile scc_t *sp = (scc_t *) & (cp->cp_scc[SCC_SM]);
 409        volatile cbd_t *bd;
 410        volatile hdlc_pram_t *hp;
 411        uchar smimsg[SMI_MSGLEN];
 412        ushort phypcrval;
 413        uint bd_off;
 414        int pnr;
 415
 416        printf ("LXT9880: %3d Mbps\n", speed);
 417
 418        immr->im_ioport.iop_paodr |= 0x0008;    /* init PAODR: PA12 (TXD2) open drain */
 419        immr->im_ioport.iop_papar |= 0x400c;    /* init PAPAR: TXD2, RXD2, BRGO4 */
 420        immr->im_ioport.iop_padir &= 0xbff3;    /* init PADIR: BRGO4 */
 421        immr->im_ioport.iop_padir |= 0x4000;
 422
 423        /* get temporary BD; no need for permanent alloc */
 424        bd_off = dpram_base_align (8);
 425
 426        bd = (cbd_t *) (immr->im_cpm.cp_dpmem + bd_off);
 427
 428        bd->cbd_bufaddr = 0;
 429        bd->cbd_datlen = 0;
 430        bd->cbd_sc = BD_SC_WRAP | BD_SC_LAST | BD_SC_INTRPT | BD_SC_TC;
 431
 432        /* init. baudrate generator BRG4 */
 433        cp->cp_brgc4 = (0x00010000 | (50 << 1));        /* output 1 MHz */
 434
 435        cp->cp_sicr &= 0xFFFF00FF;      /* SICR: mask SCC2 */
 436        cp->cp_sicr |= 0x00001B00;      /* SICR: SCC2 clk BRG4 */
 437
 438        /* init SCC_SM register */
 439        sp->scc_psmr = 0x0000;          /* init PSMR: no additional flags */
 440        sp->scc_todr = 0x0000;
 441        sp->scc_dsr = 0x7e7e;
 442
 443        /* init. SCC_SM parameter area */
 444        hp = (hdlc_pram_t *) & cp->cp_dparam[PROFF];
 445
 446        hp->tbase = bd_off;                     /* offset from beginning of DPRAM */
 447
 448        hp->rfcr = 0x18;
 449        hp->tfcr = 0x18;
 450        hp->mrblr = 10;
 451
 452        hp->c_mask = 0x0000f0b8;
 453        hp->c_pres = 0x0000ffff;
 454
 455        hp->disfc = 0;
 456        hp->crcec = 0;
 457        hp->abtsc = 0;
 458        hp->nmarc = 0;
 459        hp->retrc = 0;
 460
 461        hp->mflr = 10;
 462
 463        hp->rfthr = 1;
 464
 465        hp->hmask = 0;
 466        hp->haddr1 = 0;
 467        hp->haddr2 = 0;
 468        hp->haddr3 = 0;
 469        hp->haddr4 = 0;
 470
 471        cp->cp_cpcr = SCC_SM << 6 | 0x0001;     /* SCC_SM: init TX/RX params */
 472        while (cp->cp_cpcr & CPM_CR_FLG);
 473
 474        /* clear all outstanding SCC events */
 475        sp->scc_scce = ~0;
 476
 477        /* enable transmitter: GSMR_L: TPL=2(16bits), TPP=3(all ones), ENT */
 478        sp->scc_gsmrh = 0;
 479        sp->scc_gsmrl |= SCC_GSMRL_TPL_16 | SCC_GSMRL_TPP_ALL1 |
 480                        SCC_GSMRL_ENT | SCC_GSMRL_MODE_HDLC;
 481
 482#if 0
 483        smimsg[0] = 0x00;                       /* CHIP/HUB ID */
 484        smimsg[1] = 0x38;                       /* WRITE CMD */
 485        smimsg[2] = (RPRESET_ADDR << 4) & 0xf0;
 486        smimsg[3] = RPRESET_ADDR >> 4;
 487        smimsg[4] = 0x01;
 488        smimsg[5] = 0x00;
 489        smimsg[6] = 0x00;
 490        smimsg[7] = 0x00;
 491
 492        send_smi_frame (sp, bd, smimsg);
 493#endif
 494
 495        smimsg[0] = 0x7f;                       /* BROADCAST */
 496        smimsg[1] = 0x34;                       /* ASSIGN HUB ID */
 497        smimsg[2] = 0x00;
 498        smimsg[3] = 0x00;
 499        smimsg[4] = 0x00;                       /* HUB ID = 0 */
 500        smimsg[5] = 0x00;
 501        smimsg[6] = 0x00;
 502        smimsg[7] = 0x00;
 503
 504        send_smi_frame (sp, bd, smimsg);
 505
 506        smimsg[0] = 0x7f;                       /* BROADCAST */
 507        smimsg[1] = 0x3c;                       /* SET ARBOUT TO 0 */
 508        smimsg[2] = 0x00;                       /* ADDRESS = 0 */
 509        smimsg[3] = 0x00;
 510        smimsg[4] = 0x00;                       /* DATA = 0 */
 511        smimsg[5] = 0x00;
 512        smimsg[6] = 0x00;
 513        smimsg[7] = 0x00;
 514
 515        send_smi_frame (sp, bd, smimsg);
 516
 517        if (speed == 100) {
 518                phypcrval = PHYPCR_SPEED;       /* 100 MBIT, disable autoneg. */
 519        } else {
 520                phypcrval = 0;                  /* 10 MBIT, disable autoneg. */
 521        }
 522
 523        /* send MSGs */
 524        for (pnr = 0; pnr < 8; pnr++) {
 525                smimsg[0] = 0x00;               /* CHIP/HUB ID */
 526                smimsg[1] = 0x38;               /* WRITE CMD */
 527                smimsg[2] = ((PHYPCR_ADDR + pnr) << 4) & 0xf0;
 528                smimsg[3] = (PHYPCR_ADDR + pnr) >> 4;
 529                smimsg[4] = (unsigned char) (phypcrval & 0xff);
 530                smimsg[5] = (unsigned char) (phypcrval >> 8);
 531                smimsg[6] = 0x00;
 532                smimsg[7] = 0x00;
 533
 534                send_smi_frame (sp, bd, smimsg);
 535        }
 536
 537        smimsg[0] = 0x00;                       /* CHIP/HUB ID */
 538        smimsg[1] = 0x38;                       /* WRITE CMD */
 539        smimsg[2] = (PHYGPCR_ADDR << 4) & 0xf0;
 540        smimsg[3] = PHYGPCR_ADDR >> 4;
 541        smimsg[4] = 0xff;                       /* enable port 1-8 */
 542        smimsg[5] = 0x01;                       /* enable MII1 (0x01) */
 543        smimsg[6] = 0x00;
 544        smimsg[7] = 0x00;
 545
 546        send_smi_frame (sp, bd, smimsg);
 547
 548        smimsg[0] = 0x00;                       /* CHIP/HUB ID */
 549        smimsg[1] = 0x38;                       /* WRITE CMD */
 550        smimsg[2] = (LEDPCR_ADDR << 4) & 0xf0;
 551        smimsg[3] = LEDPCR_ADDR >> 4;
 552        smimsg[4] = 0xaa;                       /* Port 1-8 Conf.bits = 10 (Hardware control) */
 553        smimsg[5] = 0xaa;
 554        smimsg[6] = 0x00;
 555        smimsg[7] = 0x00;
 556
 557        send_smi_frame (sp, bd, smimsg);
 558
 559        /*
 560         * Disable Transmitter (so that we can free the BD, too)
 561         */
 562        sp->scc_gsmrl &= ~SCC_GSMRL_ENT;
 563}
 564
 565/* ------------------------------------------------------------------------- */
 566
 567static void send_smi_frame (volatile scc_t * sp, volatile cbd_t * bd,
 568                                                        uchar * msg)
 569{
 570#ifdef DEBUG
 571        unsigned hub, chip, cmd, length, addr;
 572
 573        hub = msg[0] & 0x1F;
 574        chip = msg[0] >> 5;
 575        cmd = msg[1] & 0x1F;
 576        length = (msg[1] >> 5) | ((msg[2] & 0x0F) << 3);
 577        addr = (msg[2] >> 4) | (msg[3] << 4);
 578
 579        printf ("SMI send: Hub %02x Chip %x Cmd %02x Len %d Addr %03x: "
 580                        "%02x %02x %02x %02x\n",
 581                        hub, chip, cmd, length, addr, msg[4], msg[5], msg[6], msg[7]);
 582#endif /* DEBUG */
 583
 584        bd->cbd_bufaddr = (uint) msg;
 585        bd->cbd_datlen = SMI_MSGLEN;
 586        bd->cbd_sc |= BD_SC_READY;
 587
 588        /* wait for msg transmitted */
 589        while ((sp->scc_scce & 0x0002) == 0);
 590        /* clear all events */
 591        sp->scc_scce = ~0;
 592}
 593
 594/* ------------------------------------------------------------------------- */
 595
 596void show_boot_progress (int status)
 597{
 598        volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
 599
 600        if (status < -32) status = -1;  /* let things compatible */
 601        status ^= 0x0F;
 602        status = (status & 0x0F) << 14;
 603        immr->im_cpm.cp_pbdat = (immr->im_cpm.cp_pbdat & ~PB_LED_ALL) | status;
 604}
 605
 606/* ------------------------------------------------------------------------- */
 607