
New board SIMPC8313 support: nand_boot.c, sdram.c, simpc8313.c
Remaining board specific files.
Signed-off-by: Ron Madrid --- board/sheldon/simpc8313/nand_boot.c | 424 +++++++++++++++++++++++++++++++++++ board/sheldon/simpc8313/sdram.c | 204 +++++++++++++++++ board/sheldon/simpc8313/simpc8313.c | 113 ++++++++++ 3 files changed, 741 insertions(+), 0 deletions(-) create mode 100644 board/sheldon/simpc8313/nand_boot.c create mode 100644 board/sheldon/simpc8313/sdram.c create mode 100644 board/sheldon/simpc8313/simpc8313.c
diff --git a/board/sheldon/simpc8313/nand_boot.c b/board/sheldon/simpc8313/nand_boot.c new file mode 100644 index 0000000..39a5616 --- /dev/null +++ b/board/sheldon/simpc8313/nand_boot.c @@ -0,0 +1,424 @@ +/* + * Copyright 2008 Sheldon Instruments, Inc. + * + * Origin from MPC8313EMDS of Nick.Spence@freescale.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include <common.h> +#include <mpc83xx.h> +#include <ns16550.h> +#include <nand.h> +#include <asm/processor.h> + +/* NAND ECC checking method - 0 = no hardware ECC check */ +#define NAND_HARD_ECC ((CFG_NAND_BR0_PRELIM >> BR_DECC_SHIFT) & 3) + +/* NAND Page Size : 0 = small page (512 bytes ), 1 = large page (2048 bytes) */ +#define NAND_PGS ((CFG_NAND_OR0_PRELIM >> OR_FCM_PGS_SHIFT) & 1) + +/* Timeout in case FCM does not complete */ +#define NAND_TIMEOUT (1000000) + +/* Delay before restarting after a fatal u-boot error */ +#define RESTART_DELAY (0x4000000) + +/* Error codes returned from nand_read_next_block() */ +#define NAND_OK (1) /* read block okay */ +#define NAND_BAD_BLOCK (0) /* block marked bad - skip block */ +#define NAND_ERR_TIMEOUT (-1) /* timeout error - fatal error */ +#define NAND_ERR_ECC (-2) /* uncorrectable ecc - fatal error */ + +/* Macros to control selected serial port */ +#if CONFIG_CONS_INDEX == 1 && defined(CFG_NS16550_COM1) +#define NS16550_COM ((NS16550_t)CFG_NS16550_COM1) +#elif CONFIG_CONS_INDEX == 2 && defined(CFG_NS16550_COM2) +#define NS16550_COM ((NS16550_t)CFG_NS16550_COM2) +#else +#warning "*****************************" +#warning "** No console port defined **" +#warning "*****************************" +#define NS16550_COM ((NS16550_t)0) +#define CFG_NAND_BOOT_QUIET +#endif /* CONFIG_CONS_INDEX */ + +/* Quiet Boot - only prints fatal error messages */ +#if defined(CFG_NAND_BOOT_QUIET) +#define status_putc(c) { while (0); } +#define status_puts(s) { while (0); } +#else +#define status_putc(c) { putc(c); } +#define status_puts(s) { puts(s); } +#endif /* CFG_NAND_BOOT_QUIET */ + +#if !(NAND_HARD_ECC) +const u_char ecc_pos[] = { +#if (NAND_PGS) + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63 +#else + 0, 1, 2, 3, 6, 7 +#endif /* NAND_PGS */ +}; +#endif /* !(NAND_HARD_ECC) */ + +/* u-boot version string from start.S */ +extern char version_string[]; + +/* nand_ecc.c */ +extern int nand_correct_data (u_char * dat, const u_char * ecc_pos, int blocks); + +/* hang */ +void hang (void) +{ + while(1); +} + +#define LCRVAL LCR_8N1 /* 8 data, 1 stop, no parity */ +#define MCRVAL (MCR_DTR | MCR_RTS) /* RTS/DTR */ +#define FCRVAL (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR) /* Clear & enable FIFOs */ + +static +void NS16550a_init (int baud_divisor) +{ + if (NS16550_COM) { + NS16550_COM->ier = 0x00; + NS16550_COM->lcr = LCR_BKSE | LCRVAL; + NS16550_COM->dll = baud_divisor & 0xff; + NS16550_COM->dlm = (baud_divisor >> 8) & 0xff; + NS16550_COM->lcr = LCRVAL; + NS16550_COM->mcr = MCRVAL; + NS16550_COM->fcr = FCRVAL; + } +} + +/* print a single character, with an extra line feed for return characters */ +void putc (const char c) +{ + if (NS16550_COM) { + if (c == '\n') { + while ((NS16550_COM->lsr & LSR_THRE) == 0); + NS16550_COM->thr = '\r'; + } + while ((NS16550_COM->lsr & LSR_THRE) == 0); + NS16550_COM->thr = c; + } +} + +/* print an entire null terminated string */ +void puts (const char *s) +{ + while (*s) { + putc (*s++); + } +} + +/* read the next block from NAND flash and store it at the supplied address + * + * return values: + * NAND_OK - block was successfully read and copied to the destination + * NAND_BAD_BLOCK - block was marked bad so should be skipped + * NAND_ERR_TIMEOUT - page read did not complete (fatal error) + * NAND_ERR_ECC - uncorrectable ECC (fatal error) + */ +static +int nand_read_next_block (unsigned int *dst) +{ + volatile immap_t *im = (immap_t *) CFG_IMMR; + volatile lbus83xx_t *lbc = &im->lbus; + int buf_num; + int page; + unsigned char *srcc; + unsigned int *src; + int ecc_err; + int ctr; + unsigned int status; +#if !(NAND_HARD_ECC) + int ecc_cnt; + char ecc_char; + + ecc_cnt = 0; +#endif /* !(NAND_HARD_ECC) */ + + ecc_err = 0; + srcc = 0; + + /* Enable FCM detection of timeouts, ECC errors and completion */ + lbc->ltedr = 0; + + lbc->fbcr = 0; /* read entire page to enable ECC */ + lbc->fbar++; /* read next block, follows boot loaded block */ +#if (NAND_PGS) + lbc->fir = (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CA << FIR_OP1_SHIFT) | + (FIR_OP_PA << FIR_OP2_SHIFT) | + (FIR_OP_CW1 << FIR_OP3_SHIFT) | + (FIR_OP_RBW << FIR_OP4_SHIFT); +#else + lbc->fir = (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CA << FIR_OP1_SHIFT) | + (FIR_OP_PA << FIR_OP2_SHIFT) | + (FIR_OP_RBW << FIR_OP3_SHIFT); +#endif /* NAND_PGS */ + lbc->fcr = (NAND_CMD_READ0 << FCR_CMD0_SHIFT) | + (NAND_CMD_READSTART << FCR_CMD1_SHIFT); + + /* read in each page of the block */ + for (page = 0; page < (CFG_NAND_BLOCK_SIZE / CFG_NAND_PAGE_SIZE); + page++) { + if (NAND_PGS) { + lbc->fpar = ((page << FPAR_LP_PI_SHIFT) & FPAR_LP_PI); + buf_num = (page & 1) << 2; + } else { + lbc->fpar = ((page << FPAR_SP_PI_SHIFT) & FPAR_SP_PI); + buf_num = page & 7; + } + lbc->fmr = CFG_NAND_FMR | 2; + + /* clear event registers */ + lbc->ltesr = lbc->ltesr; + lbc->lteatr = 0; + + /* execute special operation on bank 0 */ + lbc->lsor = 0; + asm ("sync"); + + /* copy previous page to RAM */ + if (srcc) { +#if !(NAND_HARD_ECC) + status = + nand_correct_data (srcc, ecc_pos, + sizeof (ecc_pos) / 3); + ecc_cnt += status; + if (status < 0) + ecc_err = 1; +#endif /* !(NAND_HARD_ECC) */ + src = (unsigned int *)srcc; + for (ctr = CFG_NAND_PAGE_SIZE / sizeof (unsigned int); + ctr; ctr--) { + *(dst++) = *(src++); + } + } + + /* store the source address for the next page */ + srcc = (unsigned char *)((CFG_NAND_BR0_PRELIM & BR_BA) + + (buf_num * 1024)); + + /* wait for FCM complete flag or timeout */ + status = 0; + for (ctr = NAND_TIMEOUT; ctr; ctr--) { + status = lbc->ltesr; + if (status) { + break; + } + } + + /* check for timeout or hardware ECC errors */ + if (status != LTESR_CC) { +#if (NAND_HARD_ECC) + if (status & LTESR_PAR) { + status_putc ('E'); + ecc_err = 1; + } else +#endif /* NAND_HARD_ECC */ + { + status_putc ('T'); + return NAND_ERR_TIMEOUT; + } + } + + /* Check if the block is marked as bad */ + if (page < 2) { + if (srcc[CFG_NAND_PAGE_SIZE + CFG_NAND_BAD_BLOCK_POS] != + 0xFF) { + status_putc ('B'); + return NAND_BAD_BLOCK; + } + } + } + + /* copy last page to RAM */ +#if !(NAND_HARD_ECC) + status = nand_correct_data (srcc, ecc_pos, sizeof (ecc_pos) / 3); + ecc_cnt += status; + if (status < 0) + ecc_err = 1; +#endif /* !(NAND_HARD_ECC) */ + src = (unsigned int *)srcc; + for (ctr = CFG_NAND_PAGE_SIZE / sizeof (unsigned int); ctr; ctr--) { + *(dst++) = *(src++); + } + + /* abort if any of the pages had uncorrectable errors */ + if (ecc_err && (page > 1)) { + status_putc ('U'); + return NAND_ERR_ECC; + } +#if (NAND_HARD_ECC) + status_putc ('.'); +#else +#ifdef CFG_NAND_BOOT_SHOW_ECC_NONE + ecc_char = '.'; +#else + if (ecc_cnt <= 0) { + ecc_char = '.'; +#ifdef CFG_NAND_BOOT_SHOW_ECC_NUM + } else if (ecc_cnt <= 9) { + ecc_char = '0' + ecc_cnt; + } else { + ecc_char = 'a' + ecc_cnt - 10; +#else + } else { + ecc_char = 'c'; +#endif /* CFG_NAND_BOOT_SHOW_ECC_NUM */ + } +#endif /* CFG_NAND_BOOT_SHOW_ECC_NONE */ + status_putc (ecc_char); +#endif /* NAND_HARD_ECC */ + + return NAND_OK; /* block read completed ok */ +} + +/* initial C code called from start.S prior to relocating code to DDR + * + * This performs minimal CPU initailization, DDR initialization, a few + * print statements and the calls relocate_code() to copy the code from + * the NAND flash buffer to DDR. + */ +void cpu_init_f (volatile immap_t * im) +{ + u8 spmf; + u8 clkin_div; + u32 csb_clk; + + /* RMR - Reset Mode Register - enable checkstop reset enable */ + im->reset.rmr = (RMR_CSRE & (1 << RMR_CSRE_SHIFT)); + +#if defined(CFG_NAND_BR0_PRELIM) \ + && defined(CFG_NAND_OR0_PRELIM) \ + && defined(CFG_NAND_LBLAWBAR0_PRELIM) \ + && defined(CFG_NAND_LBLAWAR0_PRELIM) + im->lbus.bank[0].br = CFG_NAND_BR0_PRELIM; + im->lbus.bank[0].or = CFG_NAND_OR0_PRELIM; + im->sysconf.lblaw[0].bar = CFG_NAND_LBLAWBAR0_PRELIM; + im->sysconf.lblaw[0].ar = CFG_NAND_LBLAWAR0_PRELIM; +#else +#error CFG_NAND_BR0_PRELIM, CFG_NAND_OR0_PRELIM, CFG_NAND_LBLAWBAR0_PRELIM & CFG_NAND_LBLAWAR0_PRELIM must be defined +#endif + clkin_div = ((im->clk.spmr & SPMR_CKID) >> SPMR_CKID_SHIFT); + spmf = ((im->reset.rcwl & HRCWL_SPMF) >> HRCWL_SPMF_SHIFT); + + if (im->reset.rcwh & HRCWH_PCI_HOST) { +#if defined(CONFIG_83XX_CLKIN) + csb_clk = CONFIG_83XX_CLKIN * spmf; +#else + csb_clk = 0; +#endif /* CONFIG_83XX_CLKIN */ + } else { +#if defined(CONFIG_83XX_PCICLK) + csb_clk = CONFIG_83XX_PCICLK * spmf * (1 + clkin_div); +#else + csb_clk = 0; +#endif /* CONFIG_83XX_PCICLK */ + } + + /* initialize selected port with appropriate baud rate */ + NS16550a_init (csb_clk / 16 / CONFIG_BAUDRATE); + + status_puts ("\nNAND-SPL "); + status_puts ((char *)(&version_string)); + + /* board specific DDR initialization */ + initdram (0); + + /* copy code to DDR and jump to it - this should not return */ + /* NOTE - code has to be copied out of NAND buffer before + * other blocks can be read. + */ + relocate_code (CFG_NAND_RELOC + 0x10000, 0, CFG_NAND_RELOC); + + /* should never get here */ + puts ("\nRelocate failed\n"); + + /* delay then restart */ + hang (); +} + +/* called after code is moved to DDR, to complete boot loading */ +void board_init_r (gd_t * id, ulong dest_addr) +{ + int blockcopy_count; + unsigned char *dst; + void (*uboot) (void* dummy, void* immr); + int ret; + + icache_enable (); /* faster execution */ + + status_puts ("\nLoading from NAND: "); + + /* + * Load U-Boot image from NAND into RAM + */ + dst = (unsigned char *)CFG_NAND_U_BOOT_DST; + blockcopy_count = ((CFG_NAND_U_BOOT_SIZE + CFG_NAND_BLOCK_SIZE - 1) + / CFG_NAND_BLOCK_SIZE); + + while (blockcopy_count) { + ret = nand_read_next_block ((unsigned int *)dst); + switch (ret) { + case NAND_OK: + /* advance to the next block */ + dst += CFG_NAND_BLOCK_SIZE; + blockcopy_count--; + break; + case NAND_BAD_BLOCK: + /* skip bad block */ + break; + default: /* fatal error */ +#if defined(CFG_NAND_BOOT_QUIET) + puts ("\nNAND SPL - "); +#else + putc ('\n'); +#endif /* CFG_NAND_BOOT_QUIET */ + if (ret == NAND_ERR_TIMEOUT) + puts ("**FATAL** : Timeout\n"); + else + puts ("**FATAL** : ECC Error\n"); + while (1) + ; + + /* delay then restart */ + hang (); + break; + } + } + + /* + * Jump to U-Boot image + */ + while(1){ + uboot = (void (*)(void* dummy, void* immr))CFG_NAND_U_BOOT_START; + (*uboot) (NULL, (void*) CFG_IMMR); + } +} + + diff --git a/board/sheldon/simpc8313/sdram.c b/board/sheldon/simpc8313/sdram.c new file mode 100644 index 0000000..9230225 --- /dev/null +++ b/board/sheldon/simpc8313/sdram.c @@ -0,0 +1,204 @@ +/* + * Copyright (C) Sheldon Instruments, Inc. 2008. + * + * Initialized by ron_madrid@hotmail.com + * Adapted from ../freescale/mpc8313erdb/sdram.c + * + * (C) Copyright 2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + */ + +#include <common.h> +#include <ioports.h> +#include <mpc83xx.h> +#include <asm/mmu.h> +#include <spd.h> +#include <command.h> + +int fixed_sdram(void); + +#if defined(CONFIG_NAND_SPL) +#define puts(v) {} +#define udelay(x) { int i,j; for (i=0; i<x; i++) for (j=0;j<10000;j++); } + +void si_read_i2c(int, int, u8*); +void si_wait_i2c(void); +#endif + +#define DDRLAWAR_SIZE 0x0000003F + +long int initdram(int board_type) +{ + volatile immap_t *im = (immap_t *) CFG_IMMR; + volatile lbus83xx_t *lbc= &im->lbus; + + u32 msize = 0; + + if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im) + return -1; + + puts("Initializing\n"); + + /* DDR SDRAM - Main SODIMM */ + im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR; + + msize = fixed_sdram(); + + /* Local Bus setup lbcr and mrtpr */ + lbc->lbcr = CFG_LBC_LBCR; + lbc->mrtpr = CFG_LBC_MRTPR; + asm("sync"); + + puts(" DDR RAM: "); + /* return total bus SDRAM size(bytes) -- DDR */ + return (msize * 1024 * 1024); +} + +/************************************************************************* + * fixed sdram init -- reads values from boot sequencer I2C + ************************************************************************/ +int fixed_sdram(void) +{ + volatile immap_t *im = (immap_t *) CFG_IMMR; + u32 msizelog2, msize = 1; +#if defined(CONFIG_NAND_SPL) + u32 i; + u8 buffer[135]; + u32 lbyte = 0, count = 135; + u32 addr = 0, data = 0; + + si_read_i2c(lbyte, count, buffer); + + for (i = 18; i < count; i+=7){ + addr = (u32)buffer[i]; + addr <<= 8; + addr |= (u32)buffer[i + 1]; + addr <<= 2; + data = (u32)buffer[i + 2]; + data <<= 8; + data |= (u32)buffer[i + 3]; + data <<= 8; + data |= (u32)buffer[i + 4]; + data <<= 8; + data |= (u32)buffer[i + 5]; + + *((u32 *)(CFG_IMMR + addr)) = data; + } + + udelay(200); + + /* enable DDR controller */ + im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN; +#endif /* (CONFIG_NAND_SPL) */ + + msizelog2 = ((im->sysconf.ddrlaw[0].ar & DDRLAWAR_SIZE) + 1); + msize <<= (msizelog2 - 20); + + return msize; +} + +#if defined(CONFIG_NAND_SPL) +void si_read_i2c(int lbyte, int count, u8 *buffer) +{
+ u8 chip = 0x50; /* boot sequencer I2C */
+ u8 ubyte;
+ u8 dummy; + u32 i; + volatile immap_t *im = (immap_t *) CFG_IMMR;
+
+ chip <<= 1;
+ ubyte = (lbyte&0xff00)>>8;
+ lbyte &= 0xff;
+
+ /* + * Set up controller + */ + im->i2c[0].cr = 0x00; + im->i2c[0].fdr = 0x3f; + im->i2c[0].dfsrr = 0x10; + im->i2c[0].adr = 0x00; + im->i2c[0].sr = 0x80; + im->i2c[0].dr = 0;
+
+ while (im->i2c[0].sr & 0x20) + ; +
+ /* + * Writing address to device + */ + im->i2c[0].cr = 0xb0; + im->i2c[0].dr = chip;
+ si_wait_i2c();
+ + im->i2c[0].cr = 0xb0; + im->i2c[0].dr = ubyte;
+
+ si_wait_i2c(); + im->i2c[0].dr = lbyte;
+ si_wait_i2c(); + im->i2c[0].cr = 0xb4; + im->i2c[0].dr = chip + 1;
+ si_wait_i2c(); + im->i2c[0].cr = 0xa0;
+
+ /* + * Dummy read + */ + dummy = im->i2c[0].dr;
+
+ si_wait_i2c();
+
+ /* + * Read actual data + */
+ for (i = 0; i < count; i++)
+ {
+ if (i == (count - 2)) /* Reached next to last byte */ + im->i2c[0].cr = 0xa8;
+ if (i == (count - 1)) /* Reached last byte */ + im->i2c[0].cr = 0x88;
+
+ /* Read byte of data */ + buffer[i] = im->i2c[0].dr;
+
+ if (i ==(count - 1))
+ break;
+ si_wait_i2c();
+
+ }
+
+ /* + * Reset controller + */ + im->i2c[0].cr = 0x80; + im->i2c[0].sr = 0x00;
+ + return; +} + +void si_wait_i2c(void){ + volatile immap_t *im = (immap_t *) CFG_IMMR;
+
+ while (!(im->i2c[0].sr & 0x02)) + ; + im->i2c[0].sr = 0; + return; +} +#endif /* CONFIG_NAND_SPL */ diff --git a/board/sheldon/simpc8313/simpc8313.c b/board/sheldon/simpc8313/simpc8313.c new file mode 100644 index 0000000..387bc06 --- /dev/null +++ b/board/sheldon/simpc8313/simpc8313.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) Sheldon Instruments, Inc. 2008. + * + * Initialized by ron_madrid@hotmail.com + * Adapted from ../freescale/mpc8313/mpc8313erdb.c + * + * ChangeLog + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + */ + +#include <common.h> +#if defined(CONFIG_OF_LIBFDT) +#include <libfdt.h> +#endif /* defined(CONFIG_OF_LIBFDT) */ +#include <pci.h> +#include <mpc83xx.h> + +DECLARE_GLOBAL_DATA_PTR; + +int board_early_init_f(void) +{ /* + * Nothing to implement here yet + */ + return 0; +} + +int checkboard(void) +{ + puts("Board: Sheldon Instruments SIMPC8313\n"); + + return 0; +} + +static struct pci_region pci_regions[] = { + { + bus_start: CFG_PCI1_MEM_BASE, + phys_start: CFG_PCI1_MEM_PHYS, + size: CFG_PCI1_MEM_SIZE, + flags: PCI_REGION_MEM | PCI_REGION_PREFETCH + }, + { + bus_start: CFG_PCI1_MMIO_BASE, + phys_start: CFG_PCI1_MMIO_PHYS, + size: CFG_PCI1_MMIO_SIZE, + flags: PCI_REGION_MEM + }, + { + bus_start: CFG_PCI1_IO_BASE, + phys_start: CFG_PCI1_IO_PHYS, + size: CFG_PCI1_IO_SIZE, + flags: PCI_REGION_IO + } +}; + +void pci_init_board(void) +{ + volatile immap_t *immr = (volatile immap_t *)CFG_IMMR; + volatile clk83xx_t *clk = (volatile clk83xx_t *)&immr->clk; + volatile law83xx_t *pci_law = immr->sysconf.pcilaw; + struct pci_region *reg[] = { pci_regions }; + int warmboot; + + /* Enable all 3 PCI_CLK_OUTPUTs. */ + clk->occr |= 0xe0000000; + + /* + * Configure PCI Local Access Windows + */ + pci_law[0].bar = CFG_PCI1_MEM_PHYS & LAWBAR_BAR; + pci_law[0].ar = LBLAWAR_EN | LBLAWAR_512MB; + + pci_law[1].bar = CFG_PCI1_IO_PHYS & LAWBAR_BAR; + pci_law[1].ar = LBLAWAR_EN | LBLAWAR_1MB; + + warmboot = gd->bd->bi_bootflags & BOOTFLAG_WARM; +#ifndef CFG_8313ERDB_BROKEN_PMC + warmboot |= immr->pmc.pmccr1 & PMCCR1_POWER_OFF; +#endif /* CFG_8313ERDB_BROKEN_PMC */ + + mpc83xx_pci_init(1, reg, warmboot); +} + +#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) + +extern void ft_cpu_setup(void *blob, bd_t *bd); +extern void ft_pci_setup(void *blob, bd_t *bd); + +#if defined(CONFIG_OF_BOARD_SETUP) +void ft_board_setup(void *blob, bd_t *bd) +{ + ft_cpu_setup(blob, bd); +#ifdef CONFIG_PCI + ft_pci_setup(blob, bd); +#endif /* CONFIG_PCI */ +} +#endif /* defined(CONFIG_OF_BOARD_SETUP) */ +#endif /* defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) */