[U-Boot-Users] [PATCH 8/8] New board SIMPC8313 support: nand_boot.c, sdram.c, simpc8313.c

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) */

Hi Ron,
On Friday 30 May 2008, Ron Madrid wrote:
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
It seems that you duplicate some of the code already available in nand_spl/nand_boot.c. I assume that you took a look at this code, right? Why didn't you try to use this infrastructure for your NAND booting support?
The current nand_spl infrastructure is used on multiple PPC4xx boards and is designed to be platform independent. It's very likely that some changes for other platforms are needed though. One enhancements that come to my mind is:
- Automatic NAND chips detection (small- vs. big-page size)
One advantage of the current nand_spl subsystem is that it uses the same NAND board/platform driver as the "normal", full blown U-Boot NAND subsystem does. So there is no need to maintain multiple NAND drivers for one board/platform.
So again, please try to use the current nand_spl infrastructure. Or at least explain why it doesn't work for you, so that we can work on these problems.
Thanks.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

On Sat, May 31, 2008 at 03:11:27PM +0200, Stefan Roese wrote:
One advantage of the current nand_spl subsystem is that it uses the same NAND board/platform driver as the "normal", full blown U-Boot NAND subsystem does. So there is no need to maintain multiple NAND drivers for one board/platform.
The elbc nand driver alone is over 4K, so that's not going to work. It could be cut down a bit by removing erase/program support, and only supporting the page size present on the target hardware, but even then I'd rather use the space for things like SPD-based SDRAM initialization.
So again, please try to use the current nand_spl infrastructure. Or at least explain why it doesn't work for you, so that we can work on these problems.
The NAND controller on the 8313 exposes a very different programming interface than what nand_spl expects. I don't think there's much that could be re-used, other than the high-level functions like nand_load().
-Scott

On Monday 02 June 2008, Scott Wood wrote:
On Sat, May 31, 2008 at 03:11:27PM +0200, Stefan Roese wrote:
One advantage of the current nand_spl subsystem is that it uses the same NAND board/platform driver as the "normal", full blown U-Boot NAND subsystem does. So there is no need to maintain multiple NAND drivers for one board/platform.
The elbc nand driver alone is over 4K, so that's not going to work. It could be cut down a bit by removing erase/program support, and only supporting the page size present on the target hardware,
Too bad.
but even then I'd rather use the space for things like SPD-based SDRAM initialization.
Are you talking about a full-blown I2C SPD DIMM detection and autoconfiguration? The code I know from 4xx is much too complicated and big for a 4k NAND booting image.
So again, please try to use the current nand_spl infrastructure. Or at least explain why it doesn't work for you, so that we can work on these problems.
The NAND controller on the 8313 exposes a very different programming interface than what nand_spl expects. I don't think there's much that could be re-used, other than the high-level functions like nand_load().
Isn't there a chance to change those NAND handling functions (like nand_read_page()) in nand_boot.c to be more flexible, that they can be used by "different" NAND drivers too? Could be that we need to simplify the current implementation somehow. Perhaps to use something as you did in your implementation like nand_read_next_block() instead of this nand_read_page(). Addressing arbitrary blocks/pages seems not needed and could cut down the current code quite a bit.
I would really like to avoid that all newer NAND booting platforms (and I expact there will come more and more in the near future), to implement their own NAND loading routines.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

Stefan Roese wrote:
On Monday 02 June 2008, Scott Wood wrote:
but even then I'd rather use the space for things like SPD-based SDRAM initialization.
Are you talking about a full-blown I2C SPD DIMM detection and autoconfiguration? The code I know from 4xx is much too complicated and big for a 4k NAND booting image.
Yeah, it may not be possible; my point was more along the the lines of if I were going to spend effort to squeeze in some bit of complex code, it wouldn't be the fully generic NAND driver with all the API glue.
The NAND controller on the 8313 exposes a very different programming interface than what nand_spl expects. I don't think there's much that could be re-used, other than the high-level functions like nand_load().
Isn't there a chance to change those NAND handling functions (like nand_read_page()) in nand_boot.c to be more flexible, that they can be used by "different" NAND drivers too? Could be that we need to simplify the current implementation somehow. Perhaps to use something as you did in your implementation like nand_read_next_block() instead of this nand_read_page(). Addressing arbitrary blocks/pages seems not needed and could cut down the current code quite a bit.
Possibly -- but the code in nand_command() and nand_read_page() is pretty much entirely inapplicable to the elbc fcm nand controller. The programming interface of elbc fcm is higher level than that.
We can share nand_load(), but that's about it.
I would really like to avoid that all newer NAND booting platforms (and I expact there will come more and more in the near future), to implement their own NAND loading routines.
Agreed -- but at the very least we'll need a couple different implementations of nand_read_next_block().
-Scott
participants (3)
-
Ron Madrid
-
Scott Wood
-
Stefan Roese