uboot/arch/powerpc/cpu/mpc83xx/cpu_init.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2004-2009 Freescale Semiconductor, Inc.
   3 *
   4 * See file CREDITS for list of people who contributed to this
   5 * project.
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License as
   9 * published by the Free Software Foundation; either version 2 of
  10 * the License, or (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 * MA 02111-1307 USA
  21 */
  22
  23#include <common.h>
  24#include <mpc83xx.h>
  25#include <ioports.h>
  26#include <asm/io.h>
  27#ifdef CONFIG_USB_EHCI_FSL
  28#include <usb/ehci-fsl.h>
  29#endif
  30
  31DECLARE_GLOBAL_DATA_PTR;
  32
  33#ifdef CONFIG_QE
  34extern qe_iop_conf_t qe_iop_conf_tab[];
  35extern void qe_config_iopin(u8 port, u8 pin, int dir,
  36                         int open_drain, int assign);
  37extern void qe_init(uint qe_base);
  38extern void qe_reset(void);
  39
  40static void config_qe_ioports(void)
  41{
  42        u8      port, pin;
  43        int     dir, open_drain, assign;
  44        int     i;
  45
  46        for (i = 0; qe_iop_conf_tab[i].assign != QE_IOP_TAB_END; i++) {
  47                port            = qe_iop_conf_tab[i].port;
  48                pin             = qe_iop_conf_tab[i].pin;
  49                dir             = qe_iop_conf_tab[i].dir;
  50                open_drain      = qe_iop_conf_tab[i].open_drain;
  51                assign          = qe_iop_conf_tab[i].assign;
  52                qe_config_iopin(port, pin, dir, open_drain, assign);
  53        }
  54}
  55#endif
  56
  57/*
  58 * Breathe some life into the CPU...
  59 *
  60 * Set up the memory map,
  61 * initialize a bunch of registers,
  62 * initialize the UPM's
  63 */
  64void cpu_init_f (volatile immap_t * im)
  65{
  66        __be32 acr_mask =
  67#ifdef CONFIG_SYS_ACR_PIPE_DEP /* Arbiter pipeline depth */
  68                ACR_PIPE_DEP |
  69#endif
  70#ifdef CONFIG_SYS_ACR_RPTCNT /* Arbiter repeat count */
  71                ACR_RPTCNT |
  72#endif
  73#ifdef CONFIG_SYS_ACR_APARK     /* Arbiter address parking mode */
  74                ACR_APARK |
  75#endif
  76#ifdef CONFIG_SYS_ACR_PARKM     /* Arbiter parking master */
  77                ACR_PARKM |
  78#endif
  79                0;
  80        __be32 acr_val =
  81#ifdef CONFIG_SYS_ACR_PIPE_DEP /* Arbiter pipeline depth */
  82                (CONFIG_SYS_ACR_PIPE_DEP << ACR_PIPE_DEP_SHIFT) |
  83#endif
  84#ifdef CONFIG_SYS_ACR_RPTCNT /* Arbiter repeat count */
  85                (CONFIG_SYS_ACR_RPTCNT << ACR_RPTCNT_SHIFT) |
  86#endif
  87#ifdef CONFIG_SYS_ACR_APARK     /* Arbiter address parking mode */
  88                (CONFIG_SYS_ACR_APARK << ACR_APARK_SHIFT) |
  89#endif
  90#ifdef CONFIG_SYS_ACR_PARKM     /* Arbiter parking master */
  91                (CONFIG_SYS_ACR_PARKM << ACR_PARKM_SHIFT) |
  92#endif
  93                0;
  94        __be32 spcr_mask =
  95#ifdef CONFIG_SYS_SPCR_OPT /* Optimize transactions between CSB and other dev */
  96                SPCR_OPT |
  97#endif
  98#ifdef CONFIG_SYS_SPCR_TSECEP /* all eTSEC's Emergency priority */
  99                SPCR_TSECEP |
 100#endif
 101#ifdef CONFIG_SYS_SPCR_TSEC1EP /* TSEC1 Emergency priority */
 102                SPCR_TSEC1EP |
 103#endif
 104#ifdef CONFIG_SYS_SPCR_TSEC2EP /* TSEC2 Emergency priority */
 105                SPCR_TSEC2EP |
 106#endif
 107                0;
 108        __be32 spcr_val =
 109#ifdef CONFIG_SYS_SPCR_OPT
 110                (CONFIG_SYS_SPCR_OPT << SPCR_OPT_SHIFT) |
 111#endif
 112#ifdef CONFIG_SYS_SPCR_TSECEP /* all eTSEC's Emergency priority */
 113                (CONFIG_SYS_SPCR_TSECEP << SPCR_TSECEP_SHIFT) |
 114#endif
 115#ifdef CONFIG_SYS_SPCR_TSEC1EP /* TSEC1 Emergency priority */
 116                (CONFIG_SYS_SPCR_TSEC1EP << SPCR_TSEC1EP_SHIFT) |
 117#endif
 118#ifdef CONFIG_SYS_SPCR_TSEC2EP /* TSEC2 Emergency priority */
 119                (CONFIG_SYS_SPCR_TSEC2EP << SPCR_TSEC2EP_SHIFT) |
 120#endif
 121                0;
 122        __be32 sccr_mask =
 123#ifdef CONFIG_SYS_SCCR_ENCCM /* Encryption clock mode */
 124                SCCR_ENCCM |
 125#endif
 126#ifdef CONFIG_SYS_SCCR_PCICM /* PCI & DMA clock mode */
 127                SCCR_PCICM |
 128#endif
 129#ifdef CONFIG_SYS_SCCR_PCIEXP1CM        /* PCIE1 clock mode */
 130                SCCR_PCIEXP1CM |
 131#endif
 132#ifdef CONFIG_SYS_SCCR_PCIEXP2CM        /* PCIE2 clock mode */
 133                SCCR_PCIEXP2CM |
 134#endif
 135#ifdef CONFIG_SYS_SCCR_TSECCM /* all TSEC's clock mode */
 136                SCCR_TSECCM |
 137#endif
 138#ifdef CONFIG_SYS_SCCR_TSEC1CM /* TSEC1 clock mode */
 139                SCCR_TSEC1CM |
 140#endif
 141#ifdef CONFIG_SYS_SCCR_TSEC2CM /* TSEC2 clock mode */
 142                SCCR_TSEC2CM |
 143#endif
 144#ifdef CONFIG_SYS_SCCR_TSEC1ON /* TSEC1 clock switch */
 145                SCCR_TSEC1ON |
 146#endif
 147#ifdef CONFIG_SYS_SCCR_TSEC2ON /* TSEC2 clock switch */
 148                SCCR_TSEC2ON |
 149#endif
 150#ifdef CONFIG_SYS_SCCR_USBMPHCM /* USB MPH clock mode */
 151                SCCR_USBMPHCM |
 152#endif
 153#ifdef CONFIG_SYS_SCCR_USBDRCM /* USB DR clock mode */
 154                SCCR_USBDRCM |
 155#endif
 156#ifdef CONFIG_SYS_SCCR_SATACM /* SATA controller clock mode */
 157                SCCR_SATACM |
 158#endif
 159                0;
 160        __be32 sccr_val =
 161#ifdef CONFIG_SYS_SCCR_ENCCM /* Encryption clock mode */
 162                (CONFIG_SYS_SCCR_ENCCM << SCCR_ENCCM_SHIFT) |
 163#endif
 164#ifdef CONFIG_SYS_SCCR_PCICM /* PCI & DMA clock mode */
 165                (CONFIG_SYS_SCCR_PCICM << SCCR_PCICM_SHIFT) |
 166#endif
 167#ifdef CONFIG_SYS_SCCR_PCIEXP1CM        /* PCIE1 clock mode */
 168                (CONFIG_SYS_SCCR_PCIEXP1CM << SCCR_PCIEXP1CM_SHIFT) |
 169#endif
 170#ifdef CONFIG_SYS_SCCR_PCIEXP2CM        /* PCIE2 clock mode */
 171                (CONFIG_SYS_SCCR_PCIEXP2CM << SCCR_PCIEXP2CM_SHIFT) |
 172#endif
 173#ifdef CONFIG_SYS_SCCR_TSECCM /* all TSEC's clock mode */
 174                (CONFIG_SYS_SCCR_TSECCM << SCCR_TSECCM_SHIFT) |
 175#endif
 176#ifdef CONFIG_SYS_SCCR_TSEC1CM /* TSEC1 clock mode */
 177                (CONFIG_SYS_SCCR_TSEC1CM << SCCR_TSEC1CM_SHIFT) |
 178#endif
 179#ifdef CONFIG_SYS_SCCR_TSEC2CM /* TSEC2 clock mode */
 180                (CONFIG_SYS_SCCR_TSEC2CM << SCCR_TSEC2CM_SHIFT) |
 181#endif
 182#ifdef CONFIG_SYS_SCCR_TSEC1ON /* TSEC1 clock switch */
 183                (CONFIG_SYS_SCCR_TSEC1ON << SCCR_TSEC1ON_SHIFT) |
 184#endif
 185#ifdef CONFIG_SYS_SCCR_TSEC2ON /* TSEC2 clock switch */
 186                (CONFIG_SYS_SCCR_TSEC2ON << SCCR_TSEC2ON_SHIFT) |
 187#endif
 188#ifdef CONFIG_SYS_SCCR_USBMPHCM /* USB MPH clock mode */
 189                (CONFIG_SYS_SCCR_USBMPHCM << SCCR_USBMPHCM_SHIFT) |
 190#endif
 191#ifdef CONFIG_SYS_SCCR_USBDRCM /* USB DR clock mode */
 192                (CONFIG_SYS_SCCR_USBDRCM << SCCR_USBDRCM_SHIFT) |
 193#endif
 194#ifdef CONFIG_SYS_SCCR_SATACM /* SATA controller clock mode */
 195                (CONFIG_SYS_SCCR_SATACM << SCCR_SATACM_SHIFT) |
 196#endif
 197                0;
 198        __be32 lcrr_mask =
 199#ifdef CONFIG_SYS_LCRR_DBYP /* PLL bypass */
 200                LCRR_DBYP |
 201#endif
 202#ifdef CONFIG_SYS_LCRR_EADC /* external address delay */
 203                LCRR_EADC |
 204#endif
 205#ifdef CONFIG_SYS_LCRR_CLKDIV /* system clock divider */
 206                LCRR_CLKDIV |
 207#endif
 208                0;
 209        __be32 lcrr_val =
 210#ifdef CONFIG_SYS_LCRR_DBYP /* PLL bypass */
 211                CONFIG_SYS_LCRR_DBYP |
 212#endif
 213#ifdef CONFIG_SYS_LCRR_EADC
 214                CONFIG_SYS_LCRR_EADC |
 215#endif
 216#ifdef CONFIG_SYS_LCRR_CLKDIV /* system clock divider */
 217                CONFIG_SYS_LCRR_CLKDIV |
 218#endif
 219                0;
 220
 221        /* Pointer is writable since we allocated a register for it */
 222        gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET);
 223
 224        /* Clear initial global data */
 225        memset ((void *) gd, 0, sizeof (gd_t));
 226
 227        /* system performance tweaking */
 228        clrsetbits_be32(&im->arbiter.acr, acr_mask, acr_val);
 229
 230        clrsetbits_be32(&im->sysconf.spcr, spcr_mask, spcr_val);
 231
 232        clrsetbits_be32(&im->clk.sccr, sccr_mask, sccr_val);
 233
 234        /* RSR - Reset Status Register - clear all status (4.6.1.3) */
 235        gd->arch.reset_status = __raw_readl(&im->reset.rsr);
 236        __raw_writel(~(RSR_RES), &im->reset.rsr);
 237
 238        /* AER - Arbiter Event Register - store status */
 239        gd->arch.arbiter_event_attributes = __raw_readl(&im->arbiter.aeatr);
 240        gd->arch.arbiter_event_address = __raw_readl(&im->arbiter.aeadr);
 241
 242        /*
 243         * RMR - Reset Mode Register
 244         * contains checkstop reset enable (4.6.1.4)
 245         */
 246        __raw_writel(RMR_CSRE & (1<<RMR_CSRE_SHIFT), &im->reset.rmr);
 247
 248        /* LCRR - Clock Ratio Register (10.3.1.16)
 249         * write, read, and isync per MPC8379ERM rev.1 CLKDEV field description
 250         */
 251        clrsetbits_be32(&im->im_lbc.lcrr, lcrr_mask, lcrr_val);
 252        __raw_readl(&im->im_lbc.lcrr);
 253        isync();
 254
 255        /* Enable Time Base & Decrementer ( so we will have udelay() )*/
 256        setbits_be32(&im->sysconf.spcr, SPCR_TBEN);
 257
 258        /* System General Purpose Register */
 259#ifdef CONFIG_SYS_SICRH
 260#if defined(CONFIG_MPC834x) || defined(CONFIG_MPC8313)
 261        /* regarding to MPC34x manual rev.1 bits 28..29 must be preserved */
 262        __raw_writel((im->sysconf.sicrh & 0x0000000C) | CONFIG_SYS_SICRH,
 263                     &im->sysconf.sicrh);
 264#else
 265        __raw_writel(CONFIG_SYS_SICRH, &im->sysconf.sicrh);
 266#endif
 267#endif
 268#ifdef CONFIG_SYS_SICRL
 269        __raw_writel(CONFIG_SYS_SICRL, &im->sysconf.sicrl);
 270#endif
 271#ifdef CONFIG_SYS_GPR1
 272        __raw_writel(CONFIG_SYS_GPR1, &im->sysconf.gpr1);
 273#endif
 274#ifdef CONFIG_SYS_DDRCDR /* DDR control driver register */
 275        __raw_writel(CONFIG_SYS_DDRCDR, &im->sysconf.ddrcdr);
 276#endif
 277#ifdef CONFIG_SYS_OBIR /* Output buffer impedance register */
 278        __raw_writel(CONFIG_SYS_OBIR, &im->sysconf.obir);
 279#endif
 280
 281#ifdef CONFIG_QE
 282        /* Config QE ioports */
 283        config_qe_ioports();
 284#endif
 285        /* Set up preliminary BR/OR regs */
 286        init_early_memctl_regs();
 287
 288        /* Local Access window setup */
 289#if defined(CONFIG_SYS_LBLAWBAR0_PRELIM) && defined(CONFIG_SYS_LBLAWAR0_PRELIM)
 290        im->sysconf.lblaw[0].bar = CONFIG_SYS_LBLAWBAR0_PRELIM;
 291        im->sysconf.lblaw[0].ar = CONFIG_SYS_LBLAWAR0_PRELIM;
 292#else
 293#error  CONFIG_SYS_LBLAWBAR0_PRELIM & CONFIG_SYS_LBLAWAR0_PRELIM must be defined
 294#endif
 295
 296#if defined(CONFIG_SYS_LBLAWBAR1_PRELIM) && defined(CONFIG_SYS_LBLAWAR1_PRELIM)
 297        im->sysconf.lblaw[1].bar = CONFIG_SYS_LBLAWBAR1_PRELIM;
 298        im->sysconf.lblaw[1].ar = CONFIG_SYS_LBLAWAR1_PRELIM;
 299#endif
 300#if defined(CONFIG_SYS_LBLAWBAR2_PRELIM) && defined(CONFIG_SYS_LBLAWAR2_PRELIM)
 301        im->sysconf.lblaw[2].bar = CONFIG_SYS_LBLAWBAR2_PRELIM;
 302        im->sysconf.lblaw[2].ar = CONFIG_SYS_LBLAWAR2_PRELIM;
 303#endif
 304#if defined(CONFIG_SYS_LBLAWBAR3_PRELIM) && defined(CONFIG_SYS_LBLAWAR3_PRELIM)
 305        im->sysconf.lblaw[3].bar = CONFIG_SYS_LBLAWBAR3_PRELIM;
 306        im->sysconf.lblaw[3].ar = CONFIG_SYS_LBLAWAR3_PRELIM;
 307#endif
 308#if defined(CONFIG_SYS_LBLAWBAR4_PRELIM) && defined(CONFIG_SYS_LBLAWAR4_PRELIM)
 309        im->sysconf.lblaw[4].bar = CONFIG_SYS_LBLAWBAR4_PRELIM;
 310        im->sysconf.lblaw[4].ar = CONFIG_SYS_LBLAWAR4_PRELIM;
 311#endif
 312#if defined(CONFIG_SYS_LBLAWBAR5_PRELIM) && defined(CONFIG_SYS_LBLAWAR5_PRELIM)
 313        im->sysconf.lblaw[5].bar = CONFIG_SYS_LBLAWBAR5_PRELIM;
 314        im->sysconf.lblaw[5].ar = CONFIG_SYS_LBLAWAR5_PRELIM;
 315#endif
 316#if defined(CONFIG_SYS_LBLAWBAR6_PRELIM) && defined(CONFIG_SYS_LBLAWAR6_PRELIM)
 317        im->sysconf.lblaw[6].bar = CONFIG_SYS_LBLAWBAR6_PRELIM;
 318        im->sysconf.lblaw[6].ar = CONFIG_SYS_LBLAWAR6_PRELIM;
 319#endif
 320#if defined(CONFIG_SYS_LBLAWBAR7_PRELIM) && defined(CONFIG_SYS_LBLAWAR7_PRELIM)
 321        im->sysconf.lblaw[7].bar = CONFIG_SYS_LBLAWBAR7_PRELIM;
 322        im->sysconf.lblaw[7].ar = CONFIG_SYS_LBLAWAR7_PRELIM;
 323#endif
 324#ifdef CONFIG_SYS_GPIO1_PRELIM
 325        im->gpio[0].dat = CONFIG_SYS_GPIO1_DAT;
 326        im->gpio[0].dir = CONFIG_SYS_GPIO1_DIR;
 327#endif
 328#ifdef CONFIG_SYS_GPIO2_PRELIM
 329        im->gpio[1].dat = CONFIG_SYS_GPIO2_DAT;
 330        im->gpio[1].dir = CONFIG_SYS_GPIO2_DIR;
 331#endif
 332#if defined(CONFIG_USB_EHCI_FSL) && defined(CONFIG_MPC831x)
 333        uint32_t temp;
 334        struct usb_ehci *ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB_ADDR;
 335
 336        /* Configure interface. */
 337        setbits_be32(&ehci->control, REFSEL_16MHZ | UTMI_PHY_EN);
 338
 339        /* Wait for clock to stabilize */
 340        do {
 341                temp = __raw_readl(&ehci->control);
 342                udelay(1000);
 343        } while (!(temp & PHY_CLK_VALID));
 344#endif
 345}
 346
 347int cpu_init_r (void)
 348{
 349#ifdef CONFIG_QE
 350        uint qe_base = CONFIG_SYS_IMMR + 0x00100000; /* QE immr base */
 351
 352        qe_init(qe_base);
 353        qe_reset();
 354#endif
 355        return 0;
 356}
 357
 358/*
 359 * Print out the bus arbiter event
 360 */
 361#if defined(CONFIG_DISPLAY_AER_FULL)
 362static int print_83xx_arb_event(int force)
 363{
 364        static char* event[] = {
 365                "Address Time Out",
 366                "Data Time Out",
 367                "Address Only Transfer Type",
 368                "External Control Word Transfer Type",
 369                "Reserved Transfer Type",
 370                "Transfer Error",
 371                "reserved",
 372                "reserved"
 373        };
 374        static char* master[] = {
 375                "e300 Core Data Transaction",
 376                "reserved",
 377                "e300 Core Instruction Fetch",
 378                "reserved",
 379                "TSEC1",
 380                "TSEC2",
 381                "USB MPH",
 382                "USB DR",
 383                "Encryption Core",
 384                "I2C Boot Sequencer",
 385                "JTAG",
 386                "reserved",
 387                "eSDHC",
 388                "PCI1",
 389                "PCI2",
 390                "DMA",
 391                "QUICC Engine 00",
 392                "QUICC Engine 01",
 393                "QUICC Engine 10",
 394                "QUICC Engine 11",
 395                "reserved",
 396                "reserved",
 397                "reserved",
 398                "reserved",
 399                "SATA1",
 400                "SATA2",
 401                "SATA3",
 402                "SATA4",
 403                "reserved",
 404                "PCI Express 1",
 405                "PCI Express 2",
 406                "TDM-DMAC"
 407        };
 408        static char *transfer[] = {
 409                "Address-only, Clean Block",
 410                "Address-only, lwarx reservation set",
 411                "Single-beat or Burst write",
 412                "reserved",
 413                "Address-only, Flush Block",
 414                "reserved",
 415                "Burst write",
 416                "reserved",
 417                "Address-only, sync",
 418                "Address-only, tlbsync",
 419                "Single-beat or Burst read",
 420                "Single-beat or Burst read",
 421                "Address-only, Kill Block",
 422                "Address-only, icbi",
 423                "Burst read",
 424                "reserved",
 425                "Address-only, eieio",
 426                "reserved",
 427                "Single-beat write",
 428                "reserved",
 429                "ecowx - Illegal single-beat write",
 430                "reserved",
 431                "reserved",
 432                "reserved",
 433                "Address-only, TLB Invalidate",
 434                "reserved",
 435                "Single-beat or Burst read",
 436                "reserved",
 437                "eciwx - Illegal single-beat read",
 438                "reserved",
 439                "Burst read",
 440                "reserved"
 441        };
 442
 443        int etype = (gd->arch.arbiter_event_attributes & AEATR_EVENT)
 444                    >> AEATR_EVENT_SHIFT;
 445        int mstr_id = (gd->arch.arbiter_event_attributes & AEATR_MSTR_ID)
 446                      >> AEATR_MSTR_ID_SHIFT;
 447        int tbst = (gd->arch.arbiter_event_attributes & AEATR_TBST)
 448                   >> AEATR_TBST_SHIFT;
 449        int tsize = (gd->arch.arbiter_event_attributes & AEATR_TSIZE)
 450                    >> AEATR_TSIZE_SHIFT;
 451        int ttype = (gd->arch.arbiter_event_attributes & AEATR_TTYPE)
 452                    >> AEATR_TTYPE_SHIFT;
 453
 454        if (!force && !gd->arch.arbiter_event_address)
 455                return 0;
 456
 457        puts("Arbiter Event Status:\n");
 458        printf("       Event Address: 0x%08lX\n",
 459               gd->arch.arbiter_event_address);
 460        printf("       Event Type:    0x%1x  = %s\n", etype, event[etype]);
 461        printf("       Master ID:     0x%02x = %s\n", mstr_id, master[mstr_id]);
 462        printf("       Transfer Size: 0x%1x  = %d bytes\n", (tbst<<3) | tsize,
 463                                tbst ? (tsize ? tsize : 8) : 16 + 8 * tsize);
 464        printf("       Transfer Type: 0x%02x = %s\n", ttype, transfer[ttype]);
 465
 466        return gd->arch.arbiter_event_address;
 467}
 468
 469#elif defined(CONFIG_DISPLAY_AER_BRIEF)
 470
 471static int print_83xx_arb_event(int force)
 472{
 473        if (!force && !gd->arch.arbiter_event_address)
 474                return 0;
 475
 476        printf("Arbiter Event Status: AEATR=0x%08lX, AEADR=0x%08lX\n",
 477                gd->arch.arbiter_event_attributes,
 478                gd->arch.arbiter_event_address);
 479
 480        return gd->arch.arbiter_event_address;
 481}
 482#endif /* CONFIG_DISPLAY_AER_xxxx */
 483
 484/*
 485 * Figure out the cause of the reset
 486 */
 487int prt_83xx_rsr(void)
 488{
 489        static struct {
 490                ulong mask;
 491                char *desc;
 492        } bits[] = {
 493                {
 494                RSR_SWSR, "Software Soft"}, {
 495                RSR_SWHR, "Software Hard"}, {
 496                RSR_JSRS, "JTAG Soft"}, {
 497                RSR_CSHR, "Check Stop"}, {
 498                RSR_SWRS, "Software Watchdog"}, {
 499                RSR_BMRS, "Bus Monitor"}, {
 500                RSR_SRS,  "External/Internal Soft"}, {
 501                RSR_HRS,  "External/Internal Hard"}
 502        };
 503        static int n = sizeof bits / sizeof bits[0];
 504        ulong rsr = gd->arch.reset_status;
 505        int i;
 506        char *sep;
 507
 508        puts("Reset Status:");
 509
 510        sep = " ";
 511        for (i = 0; i < n; i++)
 512                if (rsr & bits[i].mask) {
 513                        printf("%s%s", sep, bits[i].desc);
 514                        sep = ", ";
 515                }
 516        puts("\n");
 517
 518#if defined(CONFIG_DISPLAY_AER_FULL) || defined(CONFIG_DISPLAY_AER_BRIEF)
 519        print_83xx_arb_event(rsr & RSR_BMRS);
 520#endif
 521        puts("\n");
 522
 523        return 0;
 524}
 525