Patches by Josef Wagner, 29 Oct 2004:

- Add support for MicroSys CPU87 board
- Add support for MicroSys PM854 board
This commit is contained in:
wdenk 2005-04-03 22:35:21 +00:00
parent c1a11c19ec
commit 384cc68744
22 changed files with 4032 additions and 185 deletions

View file

@ -2,6 +2,13 @@
Changes for U-Boot 1.1.3:
======================================================================
* Patches by Josef Wagner, 29 Oct 2004:
- Add support for MicroSys CPU87 board
- Add support for MicroSys PM854 board
* Patch by Jian Zhang, 02 Nov 2004:
Add 16-bit NAND support
* Patch by Scott McNutt, 01 Nov 2004:
Add missing NIOS/NIOS2 support for "iminfo" command

15
MAKEALL
View file

@ -97,12 +97,12 @@ LIST_824x=" \
#########################################################################
LIST_8260=" \
atc cogent_mpc8260 CPU86 ep8260 \
gw8260 hymod IPHASE4539 ISPAN \
MPC8260ADS MPC8266ADS MPC8272ADS PM826 \
PM828 ppmc8260 RPXsuper rsdproto \
sacsng sbc8260 SCM TQM8260_AC \
TQM8260_AD TQM8260_AE ZPC1900 \
atc cogent_mpc8260 CPU86 CPU87 \
ep8260 gw8260 hymod IPHASE4539
ISPAN MPC8260ADS MPC8266ADS MPC8272ADS \
PM826 PM828 ppmc8260 RPXsuper \
rsdproto sacsng sbc8260 SCM \
TQM8260_AC TQM8260_AD TQM8260_AE ZPC1900 \
"
#########################################################################
@ -111,7 +111,8 @@ LIST_8260=" \
LIST_85xx=" \
MPC8540ADS MPC8541CDS MPC8555CDS MPC8560ADS \
sbc8540 sbc8560 stxgp3 TQM8540 \
PM854 sbc8540 sbc8560 stxgp3 \
TQM8540 \
"
#########################################################################

View file

@ -959,6 +959,20 @@ CPU86_ROMBOOT_config: unconfig
fi; \
echo "export CONFIG_BOOT_ROM" >> config.mk;
CPU87_config \
CPU87_ROMBOOT_config: unconfig
@./mkconfig $(call xtract_82xx,$@) ppc mpc8260 cpu87
@cd ./include ; \
if [ "$(findstring _ROMBOOT_,$@)" ] ; then \
echo "CONFIG_BOOT_ROM = y" >> config.mk ; \
echo "... booting from 8-bit flash" ; \
else \
echo "CONFIG_BOOT_ROM = n" >> config.mk ; \
echo "... booting from 64-bit flash" ; \
fi; \
echo "export CONFIG_BOOT_ROM" >> config.mk;
ep8260_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8260 ep8260
@ -1147,6 +1161,9 @@ MPC8541CDS_config: unconfig
MPC8555CDS_config: unconfig
@./mkconfig $(@:_config=) ppc mpc85xx mpc8555cds cds
PM854_config: unconfig
@./mkconfig $(@:_config=) ppc mpc85xx pm854
sbc8540_config \
sbc8540_33_config \
sbc8540_66_config: unconfig

14
README
View file

@ -2130,13 +2130,13 @@ Low Level (hardware related) configuration options:
globally (CFG_CMD_MEM).
- CONFIG_INIT_CRITICAL
[ARM only] If this variable is NOT defined, then
certain critical initializations (like setting up the
memory controller) are omitted. Normally this
variable MUST be defined for all boards. The only
exception is when U-Boot is loaded (to RAM) by some
other boot loader or by a debugger which performs
these intializations itself.
[ARM only] If this variable is NOT defined, then
certain critical initializations (like setting up the
memory controller) are omitted. Normally this
variable MUST be defined for all boards. The only
exception is when U-Boot is loaded (to RAM) by some
other boot loader or by a debugger which performs
these intializations itself.
Building the Software:
======================

40
board/cpu87/Makefile Normal file
View file

@ -0,0 +1,40 @@
#
# (C) Copyright 2001-2005
# 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,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
OBJS = $(BOARD).o flash.o
$(LIB): .depend $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
sinclude .depend
#########################################################################

40
board/cpu87/config.mk Normal file
View file

@ -0,0 +1,40 @@
#
# (C) Copyright 2001-2005
# 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,
# MA 02111-1307 USA
#
#
# CPU87 board
#
# This should be equal to the CFG_FLASH_BASE define in configs/cpu87.h
# for the "final" configuration, with U-Boot in flash, or the address
# in RAM where U-Boot is loaded at for debugging.
#
ifeq ($(CONFIG_BOOT_ROM),y)
TEXT_BASE := 0xFF800000
PLATFORM_CPPFLAGS += -DCONFIG_BOOT_ROM
else
TEXT_BASE := 0xFF000000
endif
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)

333
board/cpu87/cpu87.c Normal file
View file

@ -0,0 +1,333 @@
/*
* (C) Copyright 2001-2005
* 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,
* MA 02111-1307 USA
*/
#include <common.h>
#include <ioports.h>
#include <mpc8260.h>
#include "cpu87.h"
#include <pci.h>
/*
* I/O Port configuration table
*
* if conf is 1, then that port pin will be configured at boot time
* according to the five values podr/pdir/ppar/psor/pdat for that entry
*/
const iop_conf_t iop_conf_tab[4][32] = {
/* Port A configuration */
{ /* conf ppar psor pdir podr pdat */
/* PA31 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 MII COL */
/* PA30 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 MII CRS */
/* PA29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC1 MII TX_ER */
/* PA28 */ { 1, 1, 1, 1, 0, 0 }, /* FCC1 MII TX_EN */
/* PA27 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 MII RX_DV */
/* PA26 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 MII RX_ER */
/* PA25 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MII MDIO */
/* PA24 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MII MDC */
/* PA23 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 MII MDIO */
/* PA22 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 MII MDC */
/* PA21 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 MII TxD[3] */
/* PA20 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 MII TxD[2] */
/* PA19 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 MII TxD[1] */
/* PA18 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 MII TxD[0] */
/* PA17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 MII RxD[0] */
/* PA16 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 MII RxD[1] */
/* PA15 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 MII RxD[2] */
/* PA14 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 MII RxD[3] */
/* PA13 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MII TXSL1 */
/* PA12 */ { 1, 0, 0, 1, 0, 1 }, /* FCC2 MII TXSL0 */
/* PA11 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 MII TXSL1 */
/* PA10 */ { 1, 0, 0, 1, 0, 1 }, /* FCC1 MII TXSL0 */
/* PA9 */ { 0, 1, 0, 1, 0, 0 }, /* SMC2 TXD */
/* PA8 */ { 0, 1, 0, 0, 0, 0 }, /* SMC2 RXD */
/* PA7 */ { 0, 0, 0, 0, 0, 0 }, /* PA7 */
/* PA6 */ { 1, 0, 0, 1, 0, 1 }, /* FCC2 MII PAUSE */
/* PA5 */ { 1, 0, 0, 1, 0, 1 }, /* FCC1 MII PAUSE */
/* PA4 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MII PWRDN */
/* PA3 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 MII PWRDN */
/* PA2 */ { 0, 0, 0, 0, 0, 0 }, /* PA2 */
/* PA1 */ { 1, 0, 0, 0, 0, 0 }, /* FCC2 MII MDINT */
/* PA0 */ { 1, 0, 0, 1, 0, 0 } /* FCC1 MII MDINT */
},
/* Port B configuration */
{ /* conf ppar psor pdir podr pdat */
/* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */
/* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */
/* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */
/* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */
/* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */
/* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */
/* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */
/* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */
/* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */
/* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */
/* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */
/* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */
/* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */
/* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */
/* PB17 */ { 0, 0, 0, 0, 0, 0 }, /* PB17 */
/* PB16 */ { 0, 0, 0, 0, 0, 0 }, /* PB16 */
/* PB15 */ { 0, 0, 0, 0, 0, 0 }, /* PB15 */
/* PB14 */ { 0, 0, 0, 0, 0, 0 }, /* PB14 */
/* PB13 */ { 0, 0, 0, 0, 0, 0 }, /* PB13 */
/* PB12 */ { 0, 0, 0, 0, 0, 0 }, /* PB12 */
/* PB11 */ { 0, 0, 0, 0, 0, 0 }, /* PB11 */
/* PB10 */ { 0, 0, 0, 0, 0, 0 }, /* PB10 */
/* PB9 */ { 0, 0, 0, 0, 0, 0 }, /* PB9 */
/* PB8 */ { 0, 0, 0, 0, 0, 0 }, /* PB8 */
/* PB7 */ { 0, 0, 0, 0, 0, 0 }, /* PB7 */
/* PB6 */ { 0, 0, 0, 0, 0, 0 }, /* PB6 */
/* PB5 */ { 0, 0, 0, 0, 0, 0 }, /* PB5 */
/* PB4 */ { 0, 0, 0, 0, 0, 0 }, /* PB4 */
/* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* PB3 */
/* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* PB2 */
/* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* PB1 */
/* PB0 */ { 0, 0, 0, 0, 0, 0 } /* PB0 */
},
/* Port C */
{ /* conf ppar psor pdir podr pdat */
/* PC31 */ { 0, 0, 0, 0, 0, 0 }, /* PC31 */
/* PC30 */ { 0, 0, 0, 0, 0, 0 }, /* PC30 */
/* PC29 */ { 1, 0, 0, 0, 0, 0 }, /* SCC1 CTS */
/* PC28 */ { 1, 0, 0, 0, 0, 0 }, /* SCC2 CTS */
/* PC27 */ { 0, 0, 0, 0, 0, 0 }, /* PC27 */
/* PC26 */ { 0, 0, 0, 0, 0, 0 }, /* PC26 */
/* PC25 */ { 0, 0, 0, 0, 0, 0 }, /* PC25 */
/* PC24 */ { 0, 0, 0, 0, 0, 0 }, /* PC24 */
/* PC23 */ { 0, 0, 0, 0, 0, 0 }, /* FDC37C78 DACFD */
/* PC22 */ { 0, 0, 0, 0, 0, 0 }, /* FDC37C78 DNFD */
/* PC21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 MII RX_CLK */
/* PC20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 MII TX_CLK */
/* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK */
/* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII TX_CLK */
/* PC17 */ { 0, 0, 0, 0, 0, 0 }, /* PC17 */
/* PC16 */ { 0, 0, 0, 0, 0, 0 }, /* PC16 */
/* PC15 */ { 0, 0, 0, 0, 0, 0 }, /* PC15 */
/* PC14 */ { 0, 0, 0, 0, 0, 0 }, /* PC14 */
/* PC13 */ { 0, 0, 0, 0, 0, 0 }, /* PC13 */
/* PC12 */ { 0, 0, 0, 0, 0, 0 }, /* PC12 */
/* PC11 */ { 0, 0, 0, 0, 0, 0 }, /* PC11 */
/* PC10 */ { 0, 0, 0, 0, 0, 0 }, /* PC10 */
/* PC9 */ { 0, 0, 0, 0, 0, 0 }, /* FC9 */
/* PC8 */ { 0, 0, 0, 0, 0, 0 }, /* PC8 */
/* PC7 */ { 0, 0, 0, 0, 0, 0 }, /* PC7 */
/* PC6 */ { 0, 0, 0, 0, 0, 0 }, /* PC6 */
/* PC5 */ { 0, 0, 0, 0, 0, 0 }, /* PC5 */
/* PC4 */ { 0, 0, 0, 0, 0, 0 }, /* PC4 */
/* PC3 */ { 0, 0, 0, 0, 0, 0 }, /* PC3 */
/* PC2 */ { 0, 0, 0, 0, 0, 0 }, /* PC2 */
/* PC1 */ { 0, 0, 0, 0, 0, 0 }, /* PC1 */
/* PC0 */ { 0, 0, 0, 0, 0, 0 }, /* FDC37C78 DRQFD */
},
/* Port D */
{ /* conf ppar psor pdir podr pdat */
/* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 RXD */
/* PD30 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 TXD */
/* PD29 */ { 1, 0, 0, 1, 0, 0 }, /* SCC1 RTS */
/* PD28 */ { 1, 1, 0, 0, 0, 0 }, /* SCC2 RXD */
/* PD27 */ { 1, 1, 0, 1, 0, 0 }, /* SCC2 TXD */
/* PD26 */ { 1, 0, 0, 1, 0, 0 }, /* SCC2 RTS */
/* PD25 */ { 0, 0, 0, 0, 0, 0 }, /* PD25 */
/* PD24 */ { 0, 0, 0, 0, 0, 0 }, /* PD24 */
/* PD23 */ { 0, 0, 0, 0, 0, 0 }, /* PD23 */
/* PD22 */ { 0, 0, 0, 0, 0, 0 }, /* PD22 */
/* PD21 */ { 0, 0, 0, 0, 0, 0 }, /* PD21 */
/* PD20 */ { 0, 0, 0, 0, 0, 0 }, /* PD20 */
/* PD19 */ { 0, 0, 0, 0, 0, 0 }, /* PD19 */
/* PD18 */ { 0, 0, 0, 0, 0, 0 }, /* PD18 */
/* PD17 */ { 0, 0, 0, 0, 0, 0 }, /* PD17 */
/* PD16 */ { 0, 0, 0, 0, 0, 0 }, /* PD16 */
#if defined(CONFIG_SOFT_I2C)
/* PD15 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SDA */
/* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SCL */
#else
#if defined(CONFIG_HARD_I2C)
/* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */
/* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */
#else /* normal I/O port pins */
/* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */
/* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */
#endif
#endif
/* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* PD13 */
/* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* PD12 */
/* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* PD11 */
/* PD10 */ { 0, 0, 0, 0, 0, 0 }, /* PD10 */
/* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1 TXD */
/* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1 RXD */
/* PD7 */ { 0, 0, 0, 0, 0, 0 }, /* PD7 */
/* PD6 */ { 0, 0, 0, 0, 0, 0 }, /* PD6 */
/* PD5 */ { 0, 0, 0, 0, 0, 0 }, /* PD5 */
/* PD4 */ { 0, 0, 0, 0, 0, 0 }, /* PD4 */
/* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* PD3 */
/* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* PD2 */
/* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* PD1 */
/* PD0 */ { 0, 0, 0, 0, 0, 0 } /* PD0 */
}
};
/* ------------------------------------------------------------------------- */
/* Check Board Identity:
*/
int checkboard (void)
{
printf ("Board: CPU87 (Rev %02x)\n", CPU86_REV);
return 0;
}
/* ------------------------------------------------------------------------- */
/* Try SDRAM initialization with P/LSDMR=sdmr and ORx=orx
*
* This routine performs standard 8260 initialization sequence
* and calculates the available memory size. It may be called
* several times to try different SDRAM configurations on both
* 60x and local buses.
*/
static long int try_init (volatile memctl8260_t * memctl, ulong sdmr,
ulong orx, volatile uchar * base)
{
volatile uchar c = 0xff;
volatile uint *sdmr_ptr;
volatile uint *orx_ptr;
ulong maxsize, size;
int i;
/* We must be able to test a location outsize the maximum legal size
* to find out THAT we are outside; but this address still has to be
* mapped by the controller. That means, that the initial mapping has
* to be (at least) twice as large as the maximum expected size.
*/
maxsize = (1 + (~orx | 0x7fff)) / 2;
/* Since CFG_SDRAM_BASE is always 0 (??), we assume that
* we are configuring CS1 if base != 0
*/
sdmr_ptr = &memctl->memc_psdmr;
orx_ptr = &memctl->memc_or2;
*orx_ptr = orx;
/*
* Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
*
* "At system reset, initialization software must set up the
* programmable parameters in the memory controller banks registers
* (ORx, BRx, P/LSDMR). After all memory parameters are configured,
* system software should execute the following initialization sequence
* for each SDRAM device.
*
* 1. Issue a PRECHARGE-ALL-BANKS command
* 2. Issue eight CBR REFRESH commands
* 3. Issue a MODE-SET command to initialize the mode register
*
* The initial commands are executed by setting P/LSDMR[OP] and
* accessing the SDRAM with a single-byte transaction."
*
* The appropriate BRx/ORx registers have already been set when we
* get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
*/
*sdmr_ptr = sdmr | PSDMR_OP_PREA;
*base = c;
*sdmr_ptr = sdmr | PSDMR_OP_CBRR;
for (i = 0; i < 8; i++)
*base = c;
*sdmr_ptr = sdmr | PSDMR_OP_MRW;
*(base + CFG_MRS_OFFS) = c; /* setting MR on address lines */
*sdmr_ptr = sdmr | PSDMR_OP_NORM | PSDMR_RFEN;
*base = c;
size = get_ram_size((long *)base, maxsize);
*orx_ptr = orx | ~(size - 1);
return (size);
}
long int initdram (int board_type)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8260_t *memctl = &immap->im_memctl;
#ifndef CFG_RAMBOOT
ulong size8, size9;
#endif
long psize;
psize = 32 * 1024 * 1024;
memctl->memc_mptpr = CFG_MPTPR;
memctl->memc_psrt = CFG_PSRT;
#ifndef CFG_RAMBOOT
/* 60x SDRAM setup:
*/
size8 = try_init (memctl, CFG_PSDMR_8COL, CFG_OR2_8COL,
(uchar *) CFG_SDRAM_BASE);
size9 = try_init (memctl, CFG_PSDMR_9COL, CFG_OR2_9COL,
(uchar *) CFG_SDRAM_BASE);
if (size8 < size9) {
psize = size9;
printf ("(60x:9COL) ");
} else {
psize = try_init (memctl, CFG_PSDMR_8COL, CFG_OR2_8COL,
(uchar *) CFG_SDRAM_BASE);
printf ("(60x:8COL) ");
}
#endif /* CFG_RAMBOOT */
icache_enable ();
return (psize);
}
#if (CONFIG_COMMANDS & CFG_CMD_DOC)
extern void doc_probe (ulong physadr);
void doc_init (void)
{
doc_probe (CFG_DOC_BASE);
}
#endif
#ifdef CONFIG_PCI
struct pci_controller hose;
extern void pci_mpc8250_init(struct pci_controller *);
void pci_init_board(void)
{
pci_mpc8250_init(&hose);
}
#endif

27
board/cpu87/cpu87.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef __BOARD_CPU87__
#define __BOARD_CPU87__
#include <config.h>
#define REG8(x) (*(volatile unsigned char *)(x))
/* CPU86 register definitions */
#define CPU86_VME_EAC REG8(CFG_BCRS_BASE + 0x00)
#define CPU86_VME_SAC REG8(CFG_BCRS_BASE + 0x01)
#define CPU86_VME_MAC REG8(CFG_BCRS_BASE + 0x02)
#define CPU86_BCR REG8(CFG_BCRS_BASE + 0x03)
#define CPU86_BSR REG8(CFG_BCRS_BASE + 0x04)
#define CPU86_WDOG_RPORT REG8(CFG_BCRS_BASE + 0x05)
#define CPU86_MBOX_IRQ REG8(CFG_BCRS_BASE + 0x04)
#define CPU86_REV REG8(CFG_BCRS_BASE + 0x07)
#define CPU86_VME_IRQMASK REG8(CFG_BCRS_BASE + 0x80)
#define CPU86_VME_IRQSTATUS REG8(CFG_BCRS_BASE + 0x81)
#define CPU86_LOCAL_IRQMASK REG8(CFG_BCRS_BASE + 0x82)
#define CPU86_LOCAL_IRQSTATUS REG8(CFG_BCRS_BASE + 0x83)
#define CPU86_PMCL_IRQSTATUS REG8(CFG_BCRS_BASE + 0x84)
/* Board Control Register bits */
#define CPU86_BCR_FWPT 0x01
#define CPU86_BCR_FWRE 0x02
#endif /* __BOARD_CPU87__ */

624
board/cpu87/flash.c Normal file
View file

@ -0,0 +1,624 @@
/*
* (C) Copyright 2001-2005
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* Flash Routines for Intel devices
*
*--------------------------------------------------------------------
* 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 <mpc8xx.h>
#include "cpu87.h"
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
/*-----------------------------------------------------------------------
*/
ulong flash_int_get_size (volatile unsigned long *baseaddr,
flash_info_t * info)
{
short i;
unsigned long flashtest_h, flashtest_l;
info->sector_count = info->size = 0;
info->flash_id = FLASH_UNKNOWN;
/* Write identify command sequence and test FLASH answer
*/
baseaddr[0] = 0x00900090;
baseaddr[1] = 0x00900090;
flashtest_h = baseaddr[0]; /* manufacturer ID */
flashtest_l = baseaddr[1];
if (flashtest_h != INTEL_MANUFACT || flashtest_l != INTEL_MANUFACT)
return (0); /* no or unknown flash */
flashtest_h = baseaddr[2]; /* device ID */
flashtest_l = baseaddr[3];
if (flashtest_h != flashtest_l)
return (0);
switch (flashtest_h) {
case INTEL_ID_28F160C3B:
info->flash_id = FLASH_28F160C3B;
info->sector_count = 39;
info->size = 0x00800000; /* 4 * 2 MB = 8 MB */
break;
case INTEL_ID_28F160F3B:
info->flash_id = FLASH_28F160F3B;
info->sector_count = 39;
info->size = 0x00800000; /* 4 * 2 MB = 8 MB */
break;
case INTEL_ID_28F640C3B:
info->flash_id = FLASH_28F640C3B;
info->sector_count = 135;
info->size = 0x02000000; /* 16 * 2 MB = 32 MB */
break;
default:
return (0); /* no or unknown flash */
}
info->flash_id |= INTEL_MANUFACT << 16; /* set manufacturer offset */
if (info->flash_id & FLASH_BTYPE) {
volatile unsigned long *tmp = baseaddr;
/* set up sector start adress table (bottom sector type)
* AND unlock the sectors (if our chip is 160C3)
*/
for (i = 0; i < info->sector_count; i++) {
if (((info->flash_id & FLASH_TYPEMASK) == FLASH_28F160C3B) ||
((info->flash_id & FLASH_TYPEMASK) == FLASH_28F640C3B)) {
tmp[0] = 0x00600060;
tmp[1] = 0x00600060;
tmp[0] = 0x00D000D0;
tmp[1] = 0x00D000D0;
}
info->start[i] = (uint) tmp;
tmp += i < 8 ? 0x2000 : 0x10000; /* pointer arith */
}
}
memset (info->protect, 0, info->sector_count);
baseaddr[0] = 0x00FF00FF;
baseaddr[1] = 0x00FF00FF;
return (info->size);
}
static ulong flash_amd_get_size (vu_char *addr, flash_info_t *info)
{
short i;
uchar vendor, devid;
ulong base = (ulong)addr;
/* Write auto select command: read Manufacturer ID */
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
addr[0x0555] = 0x90;
udelay(1000);
vendor = addr[0];
devid = addr[1] & 0xff;
/* only support AMD */
if (vendor != 0x01) {
return 0;
}
vendor &= 0xf;
devid &= 0xff;
if (devid == AMD_ID_F040B) {
info->flash_id = vendor << 16 | devid;
info->sector_count = 8;
info->size = info->sector_count * 0x10000;
}
else if (devid == AMD_ID_F080B) {
info->flash_id = vendor << 16 | devid;
info->sector_count = 16;
info->size = 4 * info->sector_count * 0x10000;
}
else if (devid == AMD_ID_F016D) {
info->flash_id = vendor << 16 | devid;
info->sector_count = 32;
info->size = 4 * info->sector_count * 0x10000;
}
else {
printf ("## Unknown Flash Type: %02x\n", devid);
return 0;
}
/* check for protected sectors */
for (i = 0; i < info->sector_count; i++) {
/* sector base address */
info->start[i] = base + i * (info->size / info->sector_count);
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
/* D0 = 1 if protected */
addr = (volatile unsigned char *)(info->start[i]);
info->protect[i] = addr[2] & 1;
}
/*
* Prevent writes to uninitialized FLASH.
*/
if (info->flash_id != FLASH_UNKNOWN) {
addr = (vu_char *)info->start[0];
addr[0] = 0xF0; /* reset bank */
}
return (info->size);
}
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
unsigned long size_b0 = 0;
unsigned long size_b1 = 0;
int i;
/* Init: no FLASHes known
*/
for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
}
/* Disable flash protection */
CPU86_BCR |= (CPU86_BCR_FWPT | CPU86_BCR_FWRE);
/* Static FLASH Bank configuration here (only one bank) */
size_b0 = flash_int_get_size ((ulong *) CFG_FLASH_BASE, &flash_info[0]);
size_b1 = flash_amd_get_size ((uchar *) CFG_BOOTROM_BASE, &flash_info[1]);
if (size_b0 > 0 || size_b1 > 0) {
printf("(");
if (size_b0 > 0) {
puts ("Bank#1 - ");
print_size (size_b0, (size_b1 > 0) ? ", " : ") ");
}
if (size_b1 > 0) {
puts ("Bank#2 - ");
print_size (size_b1, ") ");
}
}
else {
printf ("## No FLASH found.\n");
return 0;
}
/* protect monitor and environment sectors
*/
#if CFG_MONITOR_BASE >= CFG_BOOTROM_BASE
if (size_b1) {
/* If U-Boot is booted from ROM the CFG_MONITOR_BASE > CFG_FLASH_BASE
* but we shouldn't protect it.
*/
flash_protect (FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE + monitor_flash_len - 1, &flash_info[1]
);
}
#else
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
flash_protect (FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE + monitor_flash_len - 1, &flash_info[0]
);
#endif
#endif
#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
# ifndef CFG_ENV_SIZE
# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
# endif
# if CFG_ENV_ADDR >= CFG_BOOTROM_BASE
if (size_b1) {
flash_protect (FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[1]);
}
# else
flash_protect (FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
# endif
#endif
return (size_b0 + size_b1);
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t * info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch ((info->flash_id >> 16) & 0xff) {
case 0x89:
printf ("INTEL ");
break;
case 0x1:
printf ("AMD ");
break;
default:
printf ("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F160C3B:
printf ("28F160C3B (16 Mbit, bottom sector)\n");
break;
case FLASH_28F160F3B:
printf ("28F160F3B (16 Mbit, bottom sector)\n");
break;
case FLASH_28F640C3B:
printf ("28F640C3B (64 M, bottom sector)\n");
break;
case AMD_ID_F040B:
printf ("AM29F040B (4 Mbit)\n");
break;
default:
printf ("Unknown Chip Type\n");
break;
}
if (info->size < 0x100000)
printf (" Size: %ld KB in %d Sectors\n",
info->size >> 10, info->sector_count);
else
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
vu_char *addr = (vu_char *)(info->start[0]);
int flag, prot, sect, l_sect;
ulong start, now, last;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
prot = 0;
for (sect = s_first; sect <= s_last; sect++) {
if (info->protect[sect])
prot++;
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
/* Check the type of erased flash
*/
if (info->flash_id >> 16 == 0x1) {
/* Erase AMD flash
*/
l_sect = -1;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
addr[0x0555] = 0x80;
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
addr = (vu_char *)(info->start[sect]);
addr[0] = 0x30;
l_sect = sect;
}
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
/*
* We wait for the last triggered sector
*/
if (l_sect < 0)
goto AMD_DONE;
start = get_timer (0);
last = start;
addr = (vu_char *)(info->start[l_sect]);
while ((addr[0] & 0x80) != 0x80) {
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
return 1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
serial_putc ('.');
last = now;
}
}
AMD_DONE:
/* reset to read mode */
addr = (volatile unsigned char *)info->start[0];
addr[0] = 0xF0; /* reset bank */
} else {
/* Erase Intel flash
*/
/* Start erase on unprotected sectors
*/
for (sect = s_first; sect <= s_last; sect++) {
volatile ulong *addr =
(volatile unsigned long *) info->start[sect];
start = get_timer (0);
last = start;
if (info->protect[sect] == 0) {
/* Disable interrupts which might cause a timeout here
*/
flag = disable_interrupts ();
/* Erase the block
*/
addr[0] = 0x00200020;
addr[1] = 0x00200020;
addr[0] = 0x00D000D0;
addr[1] = 0x00D000D0;
/* re-enable interrupts if necessary
*/
if (flag)
enable_interrupts ();
/* wait at least 80us - let's wait 1 ms
*/
udelay (1000);
last = start;
while ((addr[0] & 0x00800080) != 0x00800080 ||
(addr[1] & 0x00800080) != 0x00800080) {
if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout (erase suspended!)\n");
/* Suspend erase
*/
addr[0] = 0x00B000B0;
addr[1] = 0x00B000B0;
goto DONE;
}
/* show that we're waiting
*/
if ((now - last) > 1000) { /* every second */
serial_putc ('.');
last = now;
}
}
if (addr[0] & 0x00220022 || addr[1] & 0x00220022) {
printf ("*** ERROR: erase failed!\n");
goto DONE;
}
}
/* Clear status register and reset to read mode
*/
addr[0] = 0x00500050;
addr[1] = 0x00500050;
addr[0] = 0x00FF00FF;
addr[1] = 0x00FF00FF;
}
}
printf (" done\n");
DONE:
return 0;
}
static int write_word (flash_info_t *, volatile unsigned long *, ulong);
static int write_byte (flash_info_t *info, ulong dest, uchar data);
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
ulong v;
int i, l, rc, cc = cnt, res = 0;
if (info->flash_id >> 16 == 0x1) {
/* Write to AMD 8-bit flash
*/
while (cnt > 0) {
if ((rc = write_byte(info, addr, *src)) != 0) {
return (rc);
}
addr++;
src++;
cnt--;
}
return (0);
} else {
/* Write to Intel 64-bit flash
*/
for (v=0; cc > 0; addr += 4, cc -= 4 - l) {
l = (addr & 3);
addr &= ~3;
for (i = 0; i < 4; i++) {
v = (v << 8) + (i < l || i - l >= cc ?
*((unsigned char *) addr + i) : *src++);
}
if ((res = write_word (info, (volatile unsigned long *) addr, v)) != 0)
break;
}
}
return (res);
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word (flash_info_t * info, volatile unsigned long *addr,
ulong data)
{
int flag, res = 0;
ulong start;
/* Check if Flash is (sufficiently) erased
*/
if ((*addr & data) != data)
return (2);
/* Disable interrupts which might cause a timeout here
*/
flag = disable_interrupts ();
*addr = 0x00400040;
*addr = data;
/* re-enable interrupts if necessary
*/
if (flag)
enable_interrupts ();
start = get_timer (0);
while ((*addr & 0x00800080) != 0x00800080) {
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
/* Suspend program
*/
*addr = 0x00B000B0;
res = 1;
goto OUT;
}
}
if (*addr & 0x00220022) {
printf ("*** ERROR: program failed!\n");
res = 1;
}
OUT:
/* Clear status register and reset to read mode
*/
*addr = 0x00500050;
*addr = 0x00FF00FF;
return (res);
}
/*-----------------------------------------------------------------------
* Write a byte to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_byte (flash_info_t *info, ulong dest, uchar data)
{
vu_char *addr = (vu_char *)(info->start[0]);
ulong start;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((*((vu_char *)dest) & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr[0x0555] = 0xAA;
addr[0x02AA] = 0x55;
addr[0x0555] = 0xA0;
*((vu_char *)dest) = data;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
while ((*((vu_char *)dest) & 0x80) != (data & 0x80)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
return (1);
}
}
return (0);
}
/*-----------------------------------------------------------------------
*/

123
board/cpu87/u-boot.lds Normal file
View file

@ -0,0 +1,123 @@
/*
* (C) Copyright 2001-2005
* 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,
* MA 02111-1307 USA
*/
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
.text :
{
cpu/mpc8260/start.o (.text)
*(.text)
common/environment.o(.text)
*(.fixup)
*(.got1)
. = ALIGN(16);
*(.rodata)
*(.rodata1)
*(.rodata.str1.4)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x0FFF) & 0xFFFFF000;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
__fixup_entries = (. - _FIXUP_TABLE_) >> 2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(4096);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(4096);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

48
board/pm854/Makefile Normal file
View file

@ -0,0 +1,48 @@
#
# (C) Copyright 2001-2005
# 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,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
OBJS := $(BOARD).o flash.o
SOBJS := init.o
#SOBJS :=
$(LIB): $(OBJS) $(SOBJS)
$(AR) crv $@ $(OBJS)
clean:
rm -f $(OBJS) $(SOBJS)
distclean: clean
rm -f $(LIB) core *.bak .depend
#########################################################################
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
-include .depend
#########################################################################

33
board/pm854/config.mk Normal file
View file

@ -0,0 +1,33 @@
# Copyright 2004 Freescale Semiconductor.
# Modified by Xianghua Xiao, X.Xiao@motorola.com
# (C) Copyright 2002,Motorola Inc.
#
# 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
#
#
# pm854 board
# default CCARBAR is at 0xff700000
# assume U-Boot is less than 0.5MB
#
TEXT_BASE = 0xfff80000
PLATFORM_CPPFLAGS += -DCONFIG_MPC85xx=1
PLATFORM_CPPFLAGS += -DCONFIG_MPC8540=1
PLATFORM_CPPFLAGS += -DCONFIG_E500=1

541
board/pm854/flash.c Normal file
View file

@ -0,0 +1,541 @@
/*
* (C) Copyright 2003 Motorola Inc.
* Xianghua Xiao,(X.Xiao@motorola.com)
*
* (C) Copyright 2000-2005
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com
* Add support the Sharp chips on the mpc8260ads.
* I started with board/ip860/flash.c and made changes I found in
* the MTD project by David Schleef.
*
* 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>
#if !defined(CFG_NO_FLASH)
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
#if defined(CFG_ENV_IS_IN_FLASH)
# ifndef CFG_ENV_ADDR
# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
# endif
# ifndef CFG_ENV_SIZE
# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
# endif
# ifndef CFG_ENV_SECT_SIZE
# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
# endif
#endif
#undef DEBUG
/*-----------------------------------------------------------------------
* Functions
*/
static ulong flash_get_size (vu_long *addr, flash_info_t *info);
static int write_word (flash_info_t *info, ulong dest, ulong data);
static int clear_block_lock_bit(vu_long * addr);
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
unsigned long size;
int i;
/* Init: enable write,
* or we cannot even write flash commands
*/
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
/* set the default sector offset */
}
/* Static FLASH Bank configuration here - FIXME XXX */
size = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
size, size<<20);
}
/* Re-do sizing to get full correct info */
size = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
flash_info[0].size = size;
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
/* monitor protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+monitor_flash_len-1,
&flash_info[0]);
#ifdef CFG_ENV_IS_IN_FLASH
/* ENV protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR+CFG_ENV_SECT_SIZE-1,
&flash_info[0]);
#endif
#endif
return (size);
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_INTEL: printf ("Intel "); break;
case FLASH_MAN_SHARP: printf ("Sharp "); break;
default: printf ("Unknown Vendor "); break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F016SV: printf ("28F016SV (16 Mbit, 32 x 64k)\n");
break;
case FLASH_28F160S3: printf ("28F160S3 (16 Mbit, 32 x 512K)\n");
break;
case FLASH_28F320S3: printf ("28F320S3 (32 Mbit, 64 x 512K)\n");
break;
case FLASH_LH28F016SCT: printf ("28F016SC (16 Mbit, 32 x 64K)\n");
break;
case FLASH_28F640J3A: printf ("28F640J3A (64 Mbit, 64 x 128K)\n");
break;
case FLASH_28F128J3A: printf ("28F128J3A (128 Mbit, 128 x 128K)\n");
break;
default: printf ("Unknown Chip Type\n");
break;
}
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
}
/*
* The following code cannot be run from FLASH!
*/
static ulong flash_get_size (vu_long *addr, flash_info_t *info)
{
short i;
ulong value;
ulong base = (ulong)addr;
ulong sector_offset;
#ifdef DEBUG
printf("Check flash at 0x%08x\n",(uint)addr);
#endif
/* Write "Intelligent Identifier" command: read Manufacturer ID */
*addr = 0x90909090;
udelay(20);
asm("sync");
value = addr[0] & 0x00FF00FF;
#ifdef DEBUG
printf("manufacturer=0x%x\n",(uint)value);
#endif
switch (value) {
case MT_MANUFACT: /* SHARP, MT or => Intel */
case INTEL_ALT_MANU:
info->flash_id = FLASH_MAN_INTEL;
break;
default:
printf("unknown manufacturer: %x\n", (unsigned int)value);
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* no or unknown flash */
}
value = addr[1] & 0x00FF00FF; /* device ID */
#ifdef DEBUG
printf("deviceID=0x%x\n",(uint)value);
#endif
switch (value) {
case (INTEL_ID_28F016S):
info->flash_id += FLASH_28F016SV;
info->sector_count = 32;
info->size = 0x00400000;
sector_offset = 0x20000;
break; /* => 2x2 MB */
case (INTEL_ID_28F160S3):
info->flash_id += FLASH_28F160S3;
info->sector_count = 32;
info->size = 0x00400000;
sector_offset = 0x20000;
break; /* => 2x2 MB */
case (INTEL_ID_28F320S3):
info->flash_id += FLASH_28F320S3;
info->sector_count = 64;
info->size = 0x00800000;
sector_offset = 0x20000;
break; /* => 2x4 MB */
case (INTEL_ID_28F640J3A):
info->flash_id += FLASH_28F640J3A;
info->sector_count = 64;
info->size = 0x01000000;
sector_offset = 0x40000;
break; /* => 2x8 MB */
case (INTEL_ID_28F128J3A):
info->flash_id += FLASH_28F128J3A;
info->sector_count = 128;
info->size = 0x02000000;
sector_offset = 0x40000;
break; /* => 2x16 MB */
case SHARP_ID_28F016SCL:
case SHARP_ID_28F016SCZ:
info->flash_id = FLASH_MAN_SHARP | FLASH_LH28F016SCT;
info->sector_count = 32;
info->size = 0x00800000;
sector_offset = 0x40000;
break; /* => 4x2 MB */
default:
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
}
/* set up sector start address table */
for (i = 0; i < info->sector_count; i++) {
info->start[i] = base;
base += sector_offset;
/* don't know how to check sector protection */
info->protect[i] = 0;
}
/*
* Prevent writes to uninitialized FLASH.
*/
if (info->flash_id != FLASH_UNKNOWN) {
addr = (vu_long *)info->start[0];
*addr = 0xFFFFFF; /* reset bank to read array mode */
asm("sync");
}
return (info->size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
int flag, prot, sect;
ulong start, now, last;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
if ( ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL)
&& ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_SHARP) ) {
printf ("Can't erase unknown flash type %08lx - aborted\n",
info->flash_id);
return 1;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
#ifdef DEBUG
printf("\nFlash Erase:\n");
#endif
/* Make Sure Block Lock Bit is not set. */
if(clear_block_lock_bit((vu_long *)(info->start[s_first]))){
return 1;
}
/* Start erase on unprotected sectors */
#if defined(DEBUG)
printf("Begin to erase now,s_first=0x%x s_last=0x%x...\n",s_first,s_last);
#endif
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
vu_long *addr = (vu_long *)(info->start[sect]);
asm("sync");
last = start = get_timer (0);
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
/* Reset Array */
*addr = 0xffffffff;
asm("sync");
/* Clear Status Register */
*addr = 0x50505050;
asm("sync");
/* Single Block Erase Command */
*addr = 0x20202020;
asm("sync");
/* Confirm */
*addr = 0xD0D0D0D0;
asm("sync");
if((info->flash_id & FLASH_TYPEMASK) != FLASH_LH28F016SCT) {
/* Resume Command, as per errata update */
*addr = 0xD0D0D0D0;
asm("sync");
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
while ((*addr & 0x00800080) != 0x00800080) {
if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
*addr = 0xFFFFFFFF; /* reset bank */
asm("sync");
return 1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc ('.');
last = now;
}
}
/* reset to read mode */
*addr = 0xFFFFFFFF;
asm("sync");
}
}
printf ("flash erase done\n");
return 0;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong cp, wp, data;
int i, l, rc;
wp = (addr & ~3); /* get lower word aligned address */
/*
* handle unaligned start bytes
*/
if ((l = addr - wp) != 0) {
data = 0;
for (i=0, cp=wp; i<l; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
for (; i<4 && cnt>0; ++i) {
data = (data << 8) | *src++;
--cnt;
++cp;
}
for (; cnt==0 && i<4; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
wp += 4;
}
/*
* handle word aligned part
*/
while (cnt >= 4) {
data = 0;
for (i=0; i<4; ++i) {
data = (data << 8) | *src++;
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
wp += 4;
cnt -= 4;
}
if (cnt == 0) {
return (0);
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
for (; i<4; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
return (write_word(info, wp, data));
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word (flash_info_t *info, ulong dest, ulong data)
{
vu_long *addr = (vu_long *)dest;
ulong start, csr;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((*addr & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
/* Write Command */
*addr = 0x10101010;
asm("sync");
/* Write Data */
*addr = data;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
flag = 0;
while (((csr = *addr) & 0x00800080) != 0x00800080) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
flag = 1;
break;
}
}
if (csr & 0x40404040) {
printf ("CSR indicates write error (%08lx) at %08lx\n", csr, (ulong)addr);
flag = 1;
}
/* Clear Status Registers Command */
*addr = 0x50505050;
asm("sync");
/* Reset to read array mode */
*addr = 0xFFFFFFFF;
asm("sync");
return (flag);
}
/*-----------------------------------------------------------------------
* Clear Block Lock Bit, returns:
* 0 - OK
* 1 - Timeout
*/
static int clear_block_lock_bit(vu_long * addr)
{
ulong start, now;
/* Reset Array */
*addr = 0xffffffff;
asm("sync");
/* Clear Status Register */
*addr = 0x50505050;
asm("sync");
*addr = 0x60606060;
asm("sync");
*addr = 0xd0d0d0d0;
asm("sync");
start = get_timer (0);
while((*addr & 0x00800080) != 0x00800080){
if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout on clearing Block Lock Bit\n");
*addr = 0xFFFFFFFF; /* reset bank */
asm("sync");
return 1;
}
}
return 0;
}
#endif /* !CFG_NO_FLASH */

263
board/pm854/init.S Normal file
View file

@ -0,0 +1,263 @@
/*
* Copyright 2004 Freescale Semiconductor.
* Copyright (C) 2002,2003, Motorola Inc.
* Xianghua Xiao <X.Xiao@motorola.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 <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
#include <config.h>
#include <mpc85xx.h>
/*
* TLB0 and TLB1 Entries
*
* Out of reset, TLB1's Entry 0 maps the highest 4K for CCSRBAR.
* However, CCSRBAR is then relocated to CFG_CCSRBAR right after
* these TLB entries are established.
*
* The TLB entries for DDR are dynamically setup in spd_sdram()
* and use TLB1 Entries 8 through 15 as needed according to the
* size of DDR memory.
*
* MAS0: tlbsel, esel, nv
* MAS1: valid, iprot, tid, ts, tsize
* MAS2: epn, sharen, x0, x1, w, i, m, g, e
* MAS3: rpn, u0-u3, ux, sx, uw, sw, ur, sr
*/
#define entry_start \
mflr r1 ; \
bl 0f ;
#define entry_end \
0: mflr r0 ; \
mtlr r1 ; \
blr ;
.section .bootpg, "ax"
.globl tlb1_entry
tlb1_entry:
entry_start
/*
* Number of TLB0 and TLB1 entries in the following table
*/
.long 13
#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
/*
* TLB0 4K Non-cacheable, guarded
* 0xff700000 4K Initial CCSRBAR mapping
*
* This ends up at a TLB0 Index==0 entry, and must not collide
* with other TLB0 Entries.
*/
.long TLB1_MAS0(0, 0, 0)
.long TLB1_MAS1(1, 0, 0, 0, 0)
.long TLB1_MAS2(E500_TLB_EPN(CFG_CCSRBAR_DEFAULT), 0,0,0,0,1,0,1,0)
.long TLB1_MAS3(E500_TLB_RPN(CFG_CCSRBAR_DEFAULT), 0,0,0,0,0,1,0,1,0,1)
#else
#error("Update the number of table entries in tlb1_entry")
#endif
/*
* TLB0 16K Cacheable, non-guarded
* 0xd001_0000 16K Temporary Global data for initialization
*
* Use four 4K TLB0 entries. These entries must be cacheable
* as they provide the bootstrap memory before the memory
* controler and real memory have been configured.
*
* These entries end up at TLB0 Indicies 0x10, 0x14, 0x18 and 0x1c,
* and must not collide with other TLB0 entries.
*/
.long TLB1_MAS0(0, 0, 0)
.long TLB1_MAS1(1, 0, 0, 0, 0)
.long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR),
0,0,0,0,0,0,0,0)
.long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR),
0,0,0,0,0,1,0,1,0,1)
.long TLB1_MAS0(0, 0, 0)
.long TLB1_MAS1(1, 0, 0, 0, 0)
.long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR + 4 * 1024),
0,0,0,0,0,0,0,0)
.long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR + 4 * 1024),
0,0,0,0,0,1,0,1,0,1)
.long TLB1_MAS0(0, 0, 0)
.long TLB1_MAS1(1, 0, 0, 0, 0)
.long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR + 8 * 1024),
0,0,0,0,0,0,0,0)
.long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR + 8 * 1024),
0,0,0,0,0,1,0,1,0,1)
.long TLB1_MAS0(0, 0, 0)
.long TLB1_MAS1(1, 0, 0, 0, 0)
.long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR + 12 * 1024),
0,0,0,0,0,0,0,0)
.long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR + 12 * 1024),
0,0,0,0,0,1,0,1,0,1)
/*
* TLB 0: 64M Non-cacheable, guarded
* 0xfc000000 64M FLASH (8,16,32 or 64 MB)
* Out of reset this entry is only 4K.
*/
.long TLB1_MAS0(1, 0, 0)
.long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_64M)
.long TLB1_MAS2(E500_TLB_EPN(0xfc000000), 0,0,0,0,1,0,1,0)
.long TLB1_MAS3(E500_TLB_RPN(0xfc000000), 0,0,0,0,0,1,0,1,0,1)
/*
* TLB 1: 256M Non-cacheable, guarded
* 0x80000000 256M PCI1 MEM First half
*/
.long TLB1_MAS0(1, 1, 0)
.long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M)
.long TLB1_MAS2(E500_TLB_EPN(CFG_PCI1_MEM_BASE), 0,0,0,0,1,0,1,0)
.long TLB1_MAS3(E500_TLB_RPN(CFG_PCI1_MEM_BASE), 0,0,0,0,0,1,0,1,0,1)
/*
* TLB 2: 256M Non-cacheable, guarded
* 0x90000000 256M PCI1 MEM Second half
*/
.long TLB1_MAS0(1, 2, 0)
.long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M)
.long TLB1_MAS2(E500_TLB_EPN(CFG_PCI1_MEM_BASE + 0x10000000),
0,0,0,0,1,0,1,0)
.long TLB1_MAS3(E500_TLB_RPN(CFG_PCI1_MEM_BASE + 0x10000000),
0,0,0,0,0,1,0,1,0,1)
/*
* TLB 3: 256M Non-cacheable, guarded
* 0xc0000000 256M Rapid IO MEM First half
*/
.long TLB1_MAS0(1, 3, 0)
.long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M)
.long TLB1_MAS2(E500_TLB_EPN(CFG_RIO_MEM_BASE), 0,0,0,0,1,0,1,0)
.long TLB1_MAS3(E500_TLB_RPN(CFG_RIO_MEM_BASE), 0,0,0,0,0,1,0,1,0,1)
/*
* TLB 4: 256M Non-cacheable, guarded
* 0xd0000000 256M Rapid IO MEM Second half
*/
.long TLB1_MAS0(1, 4, 0)
.long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M)
.long TLB1_MAS2(E500_TLB_EPN(CFG_RIO_MEM_BASE + 0x10000000),
0,0,0,0,1,0,1,0)
.long TLB1_MAS3(E500_TLB_RPN(CFG_RIO_MEM_BASE + 0x10000000),
0,0,0,0,0,1,0,1,0,1)
/*
* TLB 5: 64M Non-cacheable, guarded
* 0xe000_0000 1M CCSRBAR
* 0xe200_0000 16M PCI1 IO
*/
.long TLB1_MAS0(1, 5, 0)
.long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_64M)
.long TLB1_MAS2(E500_TLB_EPN(CFG_CCSRBAR), 0,0,0,0,1,0,1,0)
.long TLB1_MAS3(E500_TLB_RPN(CFG_CCSRBAR), 0,0,0,0,0,1,0,1,0,1)
/*
* TLB 6: 64M Cacheable, non-guarded
* 0xf000_0000 64M LBC SDRAM
*/
.long TLB1_MAS0(1, 6, 0)
.long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_64M)
.long TLB1_MAS2(E500_TLB_EPN(CFG_LBC_SDRAM_BASE), 0,0,0,0,0,0,0,0)
.long TLB1_MAS3(E500_TLB_RPN(CFG_LBC_SDRAM_BASE), 0,0,0,0,0,1,0,1,0,1)
#if !defined(CONFIG_SPD_EEPROM)
/*
* TLB 7: 256M DDR
* 0x00000000 256M DDR System memory
* Without SPD EEPROM configured DDR, this must be setup manually.
* Make sure the TLB count at the top of this table is correct.
* Likely it needs to be increased by two for these entries.
*/
.long TLB1_MAS0(1, 7, 0)
.long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M)
.long TLB1_MAS2(E500_TLB_EPN(CFG_DDR_SDRAM_BASE), 0,0,0,0,0,0,0,0)
.long TLB1_MAS3(E500_TLB_RPN(CFG_DDR_SDRAM_BASE), 0,0,0,0,0,1,0,1,0,1)
#endif
entry_end
/*
* LAW(Local Access Window) configuration:
*
* 0x0000_0000 0x7fff_ffff DDR 2G
* 0x8000_0000 0x9fff_ffff PCI1 MEM 512M
* 0xc000_0000 0xdfff_ffff RapidIO 512M
* 0xe000_0000 0xe000_ffff CCSR 1M
* 0xe200_0000 0xe2ff_ffff PCI1 IO 16M
* 0xf000_0000 0xf7ff_ffff SDRAM 128M
* 0xf800_0000 0xf80f_ffff BCSR 1M
* 0xfc00_0000 0xffff_ffff FLASH (boot bank) 64M
*
* Notes:
* CCSRBAR and L2-as-SRAM don't need a configured Local Access Window.
* If flash is 8M at default position (last 8M), no LAW needed.
*/
#if !defined(CONFIG_SPD_EEPROM)
#define LAWBAR0 ((CFG_DDR_SDRAM_BASE>>12) & 0xfffff)
#define LAWAR0 (LAWAR_EN | LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & LAWAR_SIZE_256M))
#else
#define LAWBAR0 0
#define LAWAR0 ((LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & LAWAR_SIZE_128M)) & ~LAWAR_EN)
#endif
#define LAWBAR1 ((CFG_PCI1_MEM_BASE>>12) & 0xfffff)
#define LAWAR1 (LAWAR_EN | LAWAR_TRGT_IF_PCIX | (LAWAR_SIZE & LAWAR_SIZE_512M))
/*
* This is not so much the SDRAM map as it is the whole localbus map.
*/
#define LAWBAR2 ((CFG_LBC_SDRAM_BASE>>12) & 0xfffff)
#define LAWAR2 (LAWAR_EN | LAWAR_TRGT_IF_LBC | (LAWAR_SIZE & LAWAR_SIZE_256M))
#define LAWBAR3 ((CFG_PCI1_IO_BASE>>12) & 0xfffff)
#define LAWAR3 (LAWAR_EN | LAWAR_TRGT_IF_PCIX | (LAWAR_SIZE & LAWAR_SIZE_16M))
/*
* Rapid IO at 0xc000_0000 for 512 M
*/
#define LAWBAR4 ((CFG_RIO_MEM_BASE>>12) & 0xfffff)
#define LAWAR4 (LAWAR_EN | LAWAR_TRGT_IF_RIO | (LAWAR_SIZE & LAWAR_SIZE_512M))
.section .bootpg, "ax"
.globl law_entry
law_entry:
entry_start
.long 0x05
.long LAWBAR0,LAWAR0,LAWBAR1,LAWAR1,LAWBAR2,LAWAR2,LAWBAR3,LAWAR3
.long LAWBAR4,LAWAR4
entry_end

296
board/pm854/pm854.c Normal file
View file

@ -0,0 +1,296 @@
/*
* Copyright 2004 Freescale Semiconductor.
* (C) Copyright 2002,2003, Motorola Inc.
* Xianghua Xiao, (X.Xiao@motorola.com)
*
* (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.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 <pci.h>
#include <asm/processor.h>
#include <asm/immap_85xx.h>
#include <spd.h>
#if defined(CONFIG_DDR_ECC)
extern void ddr_enable_ecc(unsigned int dram_size);
#endif
extern long int spd_sdram(void);
void local_bus_init(void);
void sdram_init(void);
long int fixed_sdram(void);
int board_early_init_f (void)
{
#if defined(CONFIG_PCI)
volatile immap_t *immr = (immap_t *)CFG_IMMR;
volatile ccsr_pcix_t *pci = &immr->im_pcix;
pci->peer &= 0xffffffdf; /* disable master abort */
#endif
return 0;
}
int checkboard (void)
{
puts("Board: MicroSys PM854\n");
#ifdef CONFIG_PCI
printf(" PCI1: 32 bit, %d MHz (compiled)\n",
CONFIG_SYS_CLK_FREQ / 1000000);
#else
printf(" PCI1: disabled\n");
#endif
/*
* Initialize local bus.
*/
local_bus_init();
return 0;
}
long int
initdram(int board_type)
{
long dram_size = 0;
extern long spd_sdram (void);
volatile immap_t *immap = (immap_t *)CFG_IMMR;
puts("Initializing\n");
#if defined(CONFIG_DDR_DLL)
{
volatile ccsr_gur_t *gur= &immap->im_gur;
int i,x;
x = 10;
/*
* Work around to stabilize DDR DLL
*/
gur->ddrdllcr = 0x81000000;
asm("sync;isync;msync");
udelay (200);
while (gur->ddrdllcr != 0x81000100)
{
gur->devdisr = gur->devdisr | 0x00010000;
asm("sync;isync;msync");
for (i=0; i<x; i++)
;
gur->devdisr = gur->devdisr & 0xfff7ffff;
asm("sync;isync;msync");
x++;
}
}
#endif
#if defined(CONFIG_SPD_EEPROM)
dram_size = spd_sdram ();
#else
dram_size = fixed_sdram ();
#endif
#if defined(CONFIG_DDR_ECC)
/*
* Initialize and enable DDR ECC.
*/
ddr_enable_ecc(dram_size);
#endif
puts(" DDR: ");
return dram_size;
}
/*
* Initialize Local Bus
*/
void
local_bus_init(void)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile ccsr_gur_t *gur = &immap->im_gur;
volatile ccsr_lbc_t *lbc = &immap->im_lbc;
uint clkdiv;
uint lbc_hz;
sys_info_t sysinfo;
/*
* Errata LBC11.
* Fix Local Bus clock glitch when DLL is enabled.
*
* If localbus freq is < 66Mhz, DLL bypass mode must be used.
* If localbus freq is > 133Mhz, DLL can be safely enabled.
* Between 66 and 133, the DLL is enabled with an override workaround.
*/
get_sys_info(&sysinfo);
clkdiv = lbc->lcrr & 0x0f;
lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv;
if (lbc_hz < 66) {
lbc->lcrr = CFG_LBC_LCRR | 0x80000000; /* DLL Bypass */
} else if (lbc_hz >= 133) {
lbc->lcrr = CFG_LBC_LCRR & (~0x80000000); /* DLL Enabled */
} else {
/*
* On REV1 boards, need to change CLKDIV before enable DLL.
* Default CLKDIV is 8, change it to 4 temporarily.
*/
uint pvr = get_pvr();
uint temp_lbcdll = 0;
if (pvr == PVR_85xx_REV1) {
/* FIXME: Justify the high bit here. */
lbc->lcrr = 0x10000004;
}
lbc->lcrr = CFG_LBC_LCRR & (~0x80000000); /* DLL Enabled */
udelay(200);
/*
* Sample LBC DLL ctrl reg, upshift it to set the
* override bits.
*/
temp_lbcdll = gur->lbcdllcr;
gur->lbcdllcr = (((temp_lbcdll & 0xff) << 16) | 0x80000000);
asm("sync;isync;msync");
}
}
#if defined(CFG_DRAM_TEST)
int testdram (void)
{
uint *pstart = (uint *) CFG_MEMTEST_START;
uint *pend = (uint *) CFG_MEMTEST_END;
uint *p;
printf("SDRAM test phase 1:\n");
for (p = pstart; p < pend; p++)
*p = 0xaaaaaaaa;
for (p = pstart; p < pend; p++) {
if (*p != 0xaaaaaaaa) {
printf ("SDRAM test fails at: %08x\n", (uint) p);
return 1;
}
}
printf("SDRAM test phase 2:\n");
for (p = pstart; p < pend; p++)
*p = 0x55555555;
for (p = pstart; p < pend; p++) {
if (*p != 0x55555555) {
printf ("SDRAM test fails at: %08x\n", (uint) p);
return 1;
}
}
printf("SDRAM test passed.\n");
return 0;
}
#endif
#if !defined(CONFIG_SPD_EEPROM)
/*************************************************************************
* fixed sdram init -- doesn't use serial presence detect.
************************************************************************/
long int fixed_sdram (void)
{
#ifndef CFG_RAMBOOT
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile ccsr_ddr_t *ddr= &immap->im_ddr;
ddr->cs0_bnds = CFG_DDR_CS0_BNDS;
ddr->cs0_config = CFG_DDR_CS0_CONFIG;
ddr->timing_cfg_1 = CFG_DDR_TIMING_1;
ddr->timing_cfg_2 = CFG_DDR_TIMING_2;
ddr->sdram_mode = CFG_DDR_MODE;
ddr->sdram_interval = CFG_DDR_INTERVAL;
#if defined (CONFIG_DDR_ECC)
ddr->err_disable = 0x0000000D;
ddr->err_sbe = 0x00ff0000;
#endif
asm("sync;isync;msync");
udelay(500);
#if defined (CONFIG_DDR_ECC)
/* Enable ECC checking */
ddr->sdram_cfg = (CFG_DDR_CONTROL | 0x20000000);
#else
ddr->sdram_cfg = CFG_DDR_CONTROL;
#endif
asm("sync; isync; msync");
udelay(500);
#endif
return CFG_SDRAM_SIZE * 1024 * 1024;
}
#endif /* !defined(CONFIG_SPD_EEPROM) */
#if defined(CONFIG_PCI)
/*
* Initialize PCI Devices, report devices found.
*/
#ifndef CONFIG_PCI_PNP
static struct pci_config_table pci_pm854_config_table[] = {
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_IDSEL_NUMBER, PCI_ANY_ID,
pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
PCI_ENET0_MEMADDR,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
} },
{ }
};
#endif
static struct pci_controller hose = {
#ifndef CONFIG_PCI_PNP
config_table: pci_pm854_config_table,
#endif
};
#endif /* CONFIG_PCI */
void
pci_init_board(void)
{
#ifdef CONFIG_PCI
extern void pci_mpc85xx_init(struct pci_controller *hose);
pci_mpc85xx_init(&hose);
#endif /* CONFIG_PCI */
}

148
board/pm854/u-boot.lds Normal file
View file

@ -0,0 +1,148 @@
/*
* (C) Copyright 2002,2003, Motorola,Inc.
* Xianghua Xiao, X.Xiao@motorola.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
*/
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
.resetvec 0xFFFFFFFC :
{
*(.resetvec)
} = 0xffff
.bootpg 0xFFFFF000 :
{
cpu/mpc85xx/start.o (.bootpg)
board/pm854/init.o (.bootpg)
} = 0xffff
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
.text :
{
cpu/mpc85xx/start.o (.text)
board/pm854/init.o (.text)
cpu/mpc85xx/traps.o (.text)
cpu/mpc85xx/interrupts.o (.text)
cpu/mpc85xx/cpu_init.o (.text)
cpu/mpc85xx/cpu.o (.text)
cpu/mpc85xx/tsec.o (.text)
cpu/mpc85xx/speed.o (.text)
cpu/mpc85xx/pci.o (.text)
common/dlmalloc.o (.text)
lib_generic/crc32.o (.text)
lib_ppc/extable.o (.text)
lib_generic/zlib.o (.text)
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
*(.rodata.str1.4)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x00FF) & 0xFFFFFF00;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
__fixup_entries = (. - _FIXUP_TABLE_) >> 2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(256);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(256);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

View file

@ -3,6 +3,9 @@
* borrowed heavily from:
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
*
* Added 16-bit nand support
* (C) 2004 Texas Instruments
*/
#include <common.h>
@ -20,10 +23,6 @@
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#ifdef CONFIG_AT91RM9200DK
#include <asm/arch/hardware.h>
#endif
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ids.h>
#include <jffs2/jffs2.h>
@ -399,10 +398,11 @@ U_BOOT_CMD(
* not marked bad, or no bad mark position is specified
* returns 1 if marked bad or otherwise invalid
*/
int check_block(struct nand_chip* nand, unsigned long pos)
int check_block (struct nand_chip *nand, unsigned long pos)
{
int retlen;
uint8_t oob_data;
uint16_t oob_data16[6];
int page0 = pos & (-nand->erasesize);
int page1 = page0 + nand->oobblock;
int badpos = oob_config.badblock_pos;
@ -413,12 +413,21 @@ int check_block(struct nand_chip* nand, unsigned long pos)
if (badpos < 0)
return 0; /* no way to check, assume OK */
/* Note - bad block marker can be on first or second page */
if (nand_read_oob(nand, page0 + badpos, 1, &retlen, &oob_data) ||
oob_data != 0xff ||
nand_read_oob(nand, page1 + badpos, 1, &retlen, &oob_data) ||
oob_data != 0xff)
return 1;
if (nand->bus16) {
if (nand_read_oob(nand, (page0 + 0), 12, &retlen, (uint8_t *)oob_data16)
|| (oob_data16[2] & 0xff00) != 0xff00)
return 1;
if (nand_read_oob(nand, (page1 + 0), 12, &retlen, (uint8_t *)oob_data16)
|| (oob_data16[2] & 0xff00) != 0xff00)
return 1;
} else {
/* Note - bad block marker can be on first or second page */
if (nand_read_oob(nand, page0 + badpos, 1, &retlen, &oob_data)
|| oob_data != 0xff
|| nand_read_oob (nand, page1 + badpos, 1, &retlen, &oob_data)
|| oob_data != 0xff)
return 1;
}
return 0;
}
@ -469,17 +478,14 @@ int nand_rw (struct nand_chip* nand, int cmd,
--len;
}
continue;
}
else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) {
} else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) {
start += erasesize;
continue;
}
else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
} else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
/* skip bad block */
start += erasesize;
continue;
}
else {
} else {
ret = 1;
break;
}
@ -491,14 +497,15 @@ int nand_rw (struct nand_chip* nand, int cmd,
if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200))
printf("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\n");
if (cmd & NANDRW_READ)
if (cmd & NANDRW_READ) {
ret = nand_read_ecc(nand, start,
min(len, eblk + erasesize - start),
&n, (u_char*)buf, eccbuf);
else
} else {
ret = nand_write_ecc(nand, start,
min(len, eblk + erasesize - start),
&n, (u_char*)buf, eccbuf);
}
if (ret)
break;
@ -568,7 +575,7 @@ static inline int NanD_Command(struct nand_chip *nand, unsigned char command)
if(command == NAND_CMD_RESET){
u_char ret_val;
NanD_Command(nand, NAND_CMD_STATUS);
do{
do {
ret_val = READ_NAND(nandptr);/* wait till ready */
} while((ret_val & 0x40) != 0x40);
}
@ -605,9 +612,11 @@ static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs)
ofs = ofs >> nand->page_shift;
if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE)
for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8)
if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8) {
WRITE_NAND_ADDRESS(ofs, nandptr);
}
}
/* Lower the ALE line */
NAND_CTL_CLRALE(nandptr);
@ -674,11 +683,12 @@ static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
* contain _one_ type of flash part, although that's not a
* hardware restriction. */
if (nand->mfr) {
if (nand->mfr == mfr && nand->id == id)
if (nand->mfr == mfr && nand->id == id) {
return 1; /* This is another the same the first */
else
} else {
printf("Flash chip at floor %d, chip %d is different:\n",
floor, chip);
}
}
/* Print and store the manufacturer and ID codes. */
@ -706,13 +716,11 @@ static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
nand->oobsize = 16;
nand->page_shift = 9;
}
nand->pageadrlen =
nand_flash_ids[i].pageadrlen;
nand->erasesize =
nand_flash_ids[i].erasesize;
nand->chips_name =
nand_flash_ids[i].name;
return 1;
nand->pageadrlen = nand_flash_ids[i].pageadrlen;
nand->erasesize = nand_flash_ids[i].erasesize;
nand->chips_name = nand_flash_ids[i].name;
nand->bus16 = nand_flash_ids[i].bus16;
return 1;
}
return 0;
}
@ -795,33 +803,74 @@ static void NanD_ScanChips(struct nand_chip *nand)
}
/* we need to be fast here, 1 us per read translates to 1 second per meg */
static void NanD_ReadBuf(struct nand_chip *nand, u_char *data_buf, int cntr)
static void NanD_ReadBuf (struct nand_chip *nand, u_char * data_buf, int cntr)
{
unsigned long nandptr = nand->IO_ADDR;
while (cntr >= 16) {
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
cntr -= 16;
}
NanD_Command (nand, NAND_CMD_READ0);
while (cntr > 0) {
*data_buf++ = READ_NAND(nandptr);
cntr--;
if (nand->bus16) {
u16 val;
while (cntr >= 16) {
val = READ_NAND (nandptr);
*data_buf++ = val & 0xff;
*data_buf++ = val >> 8;
val = READ_NAND (nandptr);
*data_buf++ = val & 0xff;
*data_buf++ = val >> 8;
val = READ_NAND (nandptr);
*data_buf++ = val & 0xff;
*data_buf++ = val >> 8;
val = READ_NAND (nandptr);
*data_buf++ = val & 0xff;
*data_buf++ = val >> 8;
val = READ_NAND (nandptr);
*data_buf++ = val & 0xff;
*data_buf++ = val >> 8;
val = READ_NAND (nandptr);
*data_buf++ = val & 0xff;
*data_buf++ = val >> 8;
val = READ_NAND (nandptr);
*data_buf++ = val & 0xff;
*data_buf++ = val >> 8;
val = READ_NAND (nandptr);
*data_buf++ = val & 0xff;
*data_buf++ = val >> 8;
cntr -= 16;
}
while (cntr > 0) {
val = READ_NAND (nandptr);
*data_buf++ = val & 0xff;
*data_buf++ = val >> 8;
cntr -= 2;
}
} else {
while (cntr >= 16) {
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
*data_buf++ = READ_NAND (nandptr);
cntr -= 16;
}
while (cntr > 0) {
*data_buf++ = READ_NAND (nandptr);
cntr--;
}
}
}
@ -842,7 +891,8 @@ static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
/* Do not allow reads past end of device */
if ((start + len) > nand->totlen) {
printf ("%s: Attempt read beyond end of device %x %x %x\n", __FUNCTION__, (uint) start, (uint) len, (uint) nand->totlen);
printf ("%s: Attempt read beyond end of device %x %x %x\n",
__FUNCTION__, (uint) start, (uint) len, (uint) nand->totlen);
*retlen = 0;
return -1;
}
@ -863,25 +913,33 @@ static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
/* Loop until all data read */
while (*retlen < len) {
#ifdef CONFIG_MTD_NAND_ECC
/* Do we have this page in cache ? */
if (nand->cache_page == page)
goto readdata;
/* Send the read command */
NanD_Command(nand, NAND_CMD_READ0);
NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
if (nand->bus16) {
NanD_Address(nand, ADDR_COLUMN_PAGE,
(page << nand->page_shift) + (col >> 1));
} else {
NanD_Address(nand, ADDR_COLUMN_PAGE,
(page << nand->page_shift) + col);
}
/* Read in a page + oob data */
NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize);
/* copy data into cache, for read out of cache and if ecc fails */
if (nand->data_cache)
memcpy (nand->data_cache, nand->data_buf, nand->oobblock + nand->oobsize);
if (nand->data_cache) {
memcpy (nand->data_cache, nand->data_buf,
nand->oobblock + nand->oobsize);
}
/* Pick the ECC bytes out of the oob data */
for (j = 0; j < 6; j++)
for (j = 0; j < 6; j++) {
ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])];
}
/* Calculate the ECC and verify it */
/* If block was not written with ECC, skip ECC */
@ -938,7 +996,14 @@ readdata:
#else
/* Send the read command */
NanD_Command(nand, NAND_CMD_READ0);
NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
if (nand->bus16) {
NanD_Address(nand, ADDR_COLUMN_PAGE,
(page << nand->page_shift) + (col >> 1));
} else {
NanD_Address(nand, ADDR_COLUMN_PAGE,
(page << nand->page_shift) + col);
}
/* Read the data directly into the return buffer */
if ((*retlen + (nand->oobblock - col)) >= len) {
NanD_ReadBuf(nand, buf + *retlen, len - *retlen);
@ -976,6 +1041,7 @@ static int nand_write_page (struct nand_chip *nand,
int i;
unsigned long nandptr = nand->IO_ADDR;
#ifdef CONFIG_MTD_NAND_ECC
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
int ecc_bytes = (nand->oobblock == 512) ? 6 : 3;
@ -992,28 +1058,53 @@ static int nand_write_page (struct nand_chip *nand,
/* Read back previous written data, if col > 0 */
if (col) {
NanD_Command(nand, NAND_CMD_READ0);
NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
for (i = 0; i < col; i++)
nand->data_buf[i] = READ_NAND (nandptr);
NanD_Command (nand, NAND_CMD_READ0);
if (nand->bus16) {
NanD_Address (nand, ADDR_COLUMN_PAGE,
(page << nand->page_shift) + (col >> 1));
} else {
NanD_Address (nand, ADDR_COLUMN_PAGE,
(page << nand->page_shift) + col);
}
if (nand->bus16) {
u16 val;
for (i = 0; i < col; i += 2) {
val = READ_NAND (nandptr);
nand->data_buf[i] = val & 0xff;
nand->data_buf[i + 1] = val >> 8;
}
} else {
for (i = 0; i < col; i++)
nand->data_buf[i] = READ_NAND (nandptr);
}
}
/* Calculate and write the ECC if we have enough data */
if ((col < nand->eccsize) && (last >= nand->eccsize)) {
nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0]));
for (i = 0; i < 3; i++)
nand->data_buf[(nand->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
if (oob_config.eccvalid_pos != -1)
nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] = 0xf0;
for (i = 0; i < 3; i++) {
nand->data_buf[(nand->oobblock +
oob_config.ecc_pos[i])] = ecc_code[i];
}
if (oob_config.eccvalid_pos != -1) {
nand->data_buf[nand->oobblock +
oob_config.eccvalid_pos] = 0xf0;
}
}
/* Calculate and write the second ECC if we have enough data */
if ((nand->oobblock == 512) && (last == nand->oobblock)) {
nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3]));
for (i = 3; i < 6; i++)
nand->data_buf[(nand->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
if (oob_config.eccvalid_pos != -1)
nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] &= 0x0f;
for (i = 3; i < 6; i++) {
nand->data_buf[(nand->oobblock +
oob_config.ecc_pos[i])] = ecc_code[i];
}
if (oob_config.eccvalid_pos != -1) {
nand->data_buf[nand->oobblock +
oob_config.eccvalid_pos] &= 0x0f;
}
}
#endif
/* Prepad for partial page programming !!! */
@ -1025,31 +1116,46 @@ static int nand_write_page (struct nand_chip *nand,
nand->data_buf[i] = 0xff;
/* Send command to begin auto page programming */
NanD_Command(nand, NAND_CMD_READ0);
NanD_Command(nand, NAND_CMD_SEQIN);
NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
NanD_Command (nand, NAND_CMD_READ0);
NanD_Command (nand, NAND_CMD_SEQIN);
if (nand->bus16) {
NanD_Address (nand, ADDR_COLUMN_PAGE,
(page << nand->page_shift) + (col >> 1));
} else {
NanD_Address (nand, ADDR_COLUMN_PAGE,
(page << nand->page_shift) + col);
}
/* Write out complete page of data */
for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
WRITE_NAND(nand->data_buf[i], nand->IO_ADDR);
if (nand->bus16) {
for (i = 0; i < (nand->oobblock + nand->oobsize); i += 2) {
WRITE_NAND (nand->data_buf[i] +
(nand->data_buf[i + 1] << 8),
nand->IO_ADDR);
}
} else {
for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
WRITE_NAND (nand->data_buf[i], nand->IO_ADDR);
}
/* Send command to actually program the data */
NanD_Command(nand, NAND_CMD_PAGEPROG);
NanD_Command(nand, NAND_CMD_STATUS);
NanD_Command (nand, NAND_CMD_PAGEPROG);
NanD_Command (nand, NAND_CMD_STATUS);
#ifdef NAND_NO_RB
{ u_char ret_val;
{
u_char ret_val;
do{
ret_val = READ_NAND(nandptr); /* wait till ready */
} while((ret_val & 0x40) != 0x40);
do {
ret_val = READ_NAND (nandptr); /* wait till ready */
} while ((ret_val & 0x40) != 0x40);
}
#endif
/* See if device thinks it succeeded */
if (READ_NAND(nand->IO_ADDR) & 0x01) {
printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, page);
if (READ_NAND (nand->IO_ADDR) & 0x01) {
printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__,
page);
return -1;
}
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
/*
* The NAND device assumes that it is always writing to
@ -1066,16 +1172,34 @@ static int nand_write_page (struct nand_chip *nand,
/* Send command to read back the page */
if (col < nand->eccsize)
NanD_Command(nand, NAND_CMD_READ0);
NanD_Command (nand, NAND_CMD_READ0);
else
NanD_Command(nand, NAND_CMD_READ1);
NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
NanD_Command (nand, NAND_CMD_READ1);
if (nand->bus16) {
NanD_Address (nand, ADDR_COLUMN_PAGE,
(page << nand->page_shift) + (col >> 1));
} else {
NanD_Address (nand, ADDR_COLUMN_PAGE,
(page << nand->page_shift) + col);
}
/* Loop through and verify the data */
for (i = col; i < last; i++) {
if (nand->data_buf[i] != readb (nand->IO_ADDR)) {
printf ("%s: Failed write verify, page 0x%08x ", __FUNCTION__, page);
return -1;
if (nand->bus16) {
for (i = col; i < last; i = +2) {
if ((nand->data_buf[i] +
(nand->data_buf[i + 1] << 8)) != READ_NAND (nand->IO_ADDR)) {
printf ("%s: Failed write verify, page 0x%08x ",
__FUNCTION__, page);
return -1;
}
}
} else {
for (i = col; i < last; i++) {
if (nand->data_buf[i] != READ_NAND (nand->IO_ADDR)) {
printf ("%s: Failed write verify, page 0x%08x ",
__FUNCTION__, page);
return -1;
}
}
}
@ -1084,19 +1208,36 @@ static int nand_write_page (struct nand_chip *nand,
* We also want to check that the ECC bytes wrote
* correctly for the same reasons stated above.
*/
NanD_Command(nand, NAND_CMD_READOOB);
NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
for (i = 0; i < nand->oobsize; i++)
nand->data_buf[i] = readb (nand->IO_ADDR);
NanD_Command (nand, NAND_CMD_READOOB);
if (nand->bus16) {
NanD_Address (nand, ADDR_COLUMN_PAGE,
(page << nand->page_shift) + (col >> 1));
} else {
NanD_Address (nand, ADDR_COLUMN_PAGE,
(page << nand->page_shift) + col);
}
if (nand->bus16) {
for (i = 0; i < nand->oobsize; i += 2) {
val = READ_NAND (nand->IO_ADDR);
nand->data_buf[i] = val & 0xff;
nand->data_buf[i + 1] = val >> 8;
}
} else {
for (i = 0; i < nand->oobsize; i++) {
nand->data_buf[i] = READ_NAND (nand->IO_ADDR);
}
}
for (i = 0; i < ecc_bytes; i++) {
if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) {
printf ("%s: Failed ECC write "
"verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
"verify, page 0x%08x, "
"%6i bytes were succesful\n",
__FUNCTION__, page, i);
return -1;
}
}
#endif
#endif
#endif /* CONFIG_MTD_NAND_ECC */
#endif /* CONFIG_MTD_NAND_VERIFY_WRITE */
return 0;
}
@ -1124,6 +1265,10 @@ static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
#ifdef CONFIG_OMAP1510
archflashwp(0,0);
#endif
#ifdef CFG_NAND_WP
NAND_WP_OFF();
#endif
NAND_ENABLE_CE(nand); /* set pin low */
/* Check the WP bit */
@ -1141,12 +1286,15 @@ static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
nand->cache_page = -1;
/* Write data into buffer */
if ((col + len) >= nand->oobblock)
for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++)
if ((col + len) >= nand->oobblock) {
for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++) {
nand->data_buf[i] = buf[(*retlen + cnt)];
else
for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++)
}
} else {
for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++) {
nand->data_buf[i] = buf[(*retlen + cnt)];
}
}
/* We use the same function for write and writev !) */
ret = nand_write_page (nand, page, col, i, ecc_code);
if (ret)
@ -1171,6 +1319,10 @@ out:
#ifdef CONFIG_OMAP1510
archflashwp(0,1);
#endif
#ifdef CFG_NAND_WP
NAND_WP_ON();
#endif
return ret;
}
@ -1197,7 +1349,13 @@ static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
NAND_ENABLE_CE(nand); /* set pin low */
NanD_Command(nand, NAND_CMD_READOOB);
NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
if (nand->bus16) {
NanD_Address(nand, ADDR_COLUMN_PAGE,
((ofs >> nand->page_shift) << nand->page_shift) +
((ofs & (nand->oobblock - 1)) >> 1));
} else {
NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
}
/* treat crossing 8-byte OOB data for 2M x 8bit devices */
/* Note: datasheet says it should automaticaly wrap to the */
@ -1247,7 +1405,13 @@ static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
/* issue the Read2 command to set the pointer to the Spare Data Area. */
NanD_Command(nand, NAND_CMD_READOOB);
NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
if (nand->bus16) {
NanD_Address(nand, ADDR_COLUMN_PAGE,
((ofs >> nand->page_shift) << nand->page_shift) +
((ofs & (nand->oobblock - 1)) >> 1));
} else {
NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
}
/* update address for 2M x 8bit devices. OOB starts on the second */
/* page to maintain compatibility with nand_read_ecc. */
@ -1260,7 +1424,13 @@ static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
/* issue the Serial Data In command to initial the Page Program process */
NanD_Command(nand, NAND_CMD_SEQIN);
NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
if (nand->bus16) {
NanD_Address(nand, ADDR_COLUMN_PAGE,
((ofs >> nand->page_shift) << nand->page_shift) +
((ofs & (nand->oobblock - 1)) >> 1));
} else {
NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
}
/* treat crossing 8-byte OOB data for 2M x 8bit devices */
/* Note: datasheet says it should automaticaly wrap to the */
@ -1274,9 +1444,9 @@ static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
NanD_Command(nand, NAND_CMD_STATUS);
#ifdef NAND_NO_RB
{ u_char ret_val;
do{
ret_val = READ_NAND(nandptr); /* wait till ready */
}while((ret_val & 0x40) != 0x40);
do {
ret_val = READ_NAND(nandptr); /* wait till ready */
} while ((ret_val & 0x40) != 0x40);
}
#endif
if (READ_NAND(nandptr) & 1) {
@ -1290,16 +1460,22 @@ static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
}
for (i = len256; i < len; i++)
WRITE_NAND(buf[i], nandptr);
if (nand->bus16) {
for (i = len256; i < len; i += 2) {
WRITE_NAND(buf[i] + (buf[i+1] << 8), nandptr);
}
} else {
for (i = len256; i < len; i++)
WRITE_NAND(buf[i], nandptr);
}
NanD_Command(nand, NAND_CMD_PAGEPROG);
NanD_Command(nand, NAND_CMD_STATUS);
#ifdef NAND_NO_RB
{ u_char ret_val;
do{
ret_val = READ_NAND(nandptr); /* wait till ready */
} while((ret_val & 0x40) != 0x40);
{ u_char ret_val;
do {
ret_val = READ_NAND(nandptr); /* wait till ready */
} while ((ret_val & 0x40) != 0x40);
}
#endif
if (READ_NAND(nandptr) & 1) {
@ -1341,6 +1517,9 @@ int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean)
/* Select the NAND device */
#ifdef CONFIG_OMAP1510
archflashwp(0,0);
#endif
#ifdef CFG_NAND_WP
NAND_WP_OFF();
#endif
NAND_ENABLE_CE(nand); /* set pin low */
@ -1379,10 +1558,10 @@ int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean)
NanD_Command(nand, NAND_CMD_STATUS);
#ifdef NAND_NO_RB
{ u_char ret_val;
do{
ret_val = READ_NAND(nandptr); /* wait till ready */
} while((ret_val & 0x40) != 0x40);
{ u_char ret_val;
do {
ret_val = READ_NAND(nandptr); /* wait till ready */
} while ((ret_val & 0x40) != 0x40);
}
#endif
if (READ_NAND(nandptr) & 1) {
@ -1403,8 +1582,7 @@ int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean)
if (nand->page256) {
p = NAND_JFFS2_OOB8_FSDAPOS;
l = NAND_JFFS2_OOB8_FSDALEN;
}
else {
} else {
p = NAND_JFFS2_OOB16_FSDAPOS;
l = NAND_JFFS2_OOB16_FSDALEN;
}
@ -1426,6 +1604,10 @@ out:
#ifdef CONFIG_OMAP1510
archflashwp(0,1);
#endif
#ifdef CFG_NAND_WP
NAND_WP_ON();
#endif
return ret;
}
@ -1498,22 +1680,38 @@ unsigned long nand_probe(unsigned long physadr)
* Pre-calculated 256-way 1 byte column parity
*/
static const u_char nand_ecc_precalc_table[] = {
0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
};
@ -1606,8 +1804,7 @@ static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
if ((d1 | d2 | d3) == 0) {
/* No errors */
return 0;
}
else {
} else {
a = (d1 ^ (d1 >> 1)) & 0x55;
b = (d2 ^ (d2 >> 1)) & 0x55;
c = (d3 ^ (d3 >> 1)) & 0x54;

View file

@ -28,21 +28,18 @@
#include <spd.h>
#include <asm/mmu.h>
#ifdef CONFIG_SPD_EEPROM
#if defined(CONFIG_DDR_ECC)
extern void dma_init(void);
extern void dma_init (void);
extern uint dma_check(void);
extern int dma_xfer(void *dest, uint count, void *src);
extern int dma_xfer (void *dest, uint count, void *src);
#endif
#ifdef CONFIG_SPD_EEPROM
#ifndef CFG_READ_SPD
#define CFG_READ_SPD i2c_read
#endif
/*
* Convert picoseconds into clock cycles (rounding up if needed).
*/
@ -60,14 +57,12 @@ picos_to_clk(int picos)
return clks;
}
unsigned int
banksize(unsigned char row_dens)
{
return ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24;
}
long int
spd_sdram(void)
{
@ -404,7 +399,6 @@ spd_sdram(void)
return memsize * 1024 * 1024;
}
#endif /* CONFIG_SPD_EEPROM */
@ -412,7 +406,6 @@ spd_sdram(void)
/*
* Initialize all of memory for ECC, then enable errors.
*/
void
ddr_enable_ecc(unsigned int dram_size)
{
@ -464,5 +457,4 @@ ddr_enable_ecc(unsigned int dram_size)
ddr->err_disable = 0x00000000;
asm("sync;isync;msync");
}
#endif /* CONFIG_DDR_ECC */

683
include/configs/CPU87.h Normal file
View file

@ -0,0 +1,683 @@
/*
* (C) Copyright 2001-2005
* 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,
* MA 02111-1307 USA
*/
/*
* board/config.h - configuration options, board specific
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/*
* High Level Configuration Options
* (easy to change)
*/
#define CONFIG_MPC8260 1 /* This is an MPC8260 CPU */
#define CONFIG_CPU87 1 /* ...on a CPU87 board */
#define CONFIG_PCI
/*
* select serial console configuration
*
* if either CONFIG_CONS_ON_SMC or CONFIG_CONS_ON_SCC is selected, then
* CONFIG_CONS_INDEX must be set to the channel number (1-2 for SMC, 1-4
* for SCC).
*
* if CONFIG_CONS_NONE is defined, then the serial console routines must
* defined elsewhere (for example, on the cogent platform, there are serial
* ports on the motherboard which are used for the serial console - see
* cogent/cma101/serial.[ch]).
*/
#undef CONFIG_CONS_ON_SMC /* define if console on SMC */
#define CONFIG_CONS_ON_SCC /* define if console on SCC */
#undef CONFIG_CONS_NONE /* define if console on something else*/
#define CONFIG_CONS_INDEX 1 /* which serial channel for console */
#if defined(CONFIG_CONS_NONE) || defined(CONFIG_CONS_USE_EXTC)
#define CONFIG_BAUDRATE 230400
#else
#define CONFIG_BAUDRATE 9600
#endif
/*
* select ethernet configuration
*
* if either CONFIG_ETHER_ON_SCC or CONFIG_ETHER_ON_FCC is selected, then
* CONFIG_ETHER_INDEX must be set to the channel number (1-4 for SCC, 1-3
* for FCC)
*
* if CONFIG_ETHER_NONE is defined, then either the ethernet routines must be
* defined elsewhere (as for the console), or CFG_CMD_NET must be removed
* from CONFIG_COMMANDS to remove support for networking.
*
*/
#undef CONFIG_ETHER_ON_SCC /* define if ether on SCC */
#define CONFIG_ETHER_ON_FCC /* define if ether on FCC */
#undef CONFIG_ETHER_NONE /* define if ether on something else */
#define CONFIG_ETHER_INDEX 1 /* which SCC/FCC channel for ethernet */
#define CONFIG_HAS_ETH1 1
#define CONFIG_HAS_ETH2 1
#if defined(CONFIG_ETHER_ON_FCC) && (CONFIG_ETHER_INDEX == 1)
/*
* - Rx-CLK is CLK11
* - Tx-CLK is CLK12
* - RAM for BD/Buffers is on the 60x Bus (see 28-13)
* - Enable Full Duplex in FSMR
*/
# define CFG_CMXFCR_MASK (CMXFCR_FC1|CMXFCR_RF1CS_MSK|CMXFCR_TF1CS_MSK)
# define CFG_CMXFCR_VALUE (CMXFCR_RF1CS_CLK11|CMXFCR_TF1CS_CLK12)
# define CFG_CPMFCR_RAMTYPE 0
# define CFG_FCC_PSMR (FCC_PSMR_FDE|FCC_PSMR_LPB)
#elif defined(CONFIG_ETHER_ON_FCC) && (CONFIG_ETHER_INDEX == 2)
/*
* - Rx-CLK is CLK13
* - Tx-CLK is CLK14
* - RAM for BD/Buffers is on the 60x Bus (see 28-13)
* - Enable Full Duplex in FSMR
*/
# define CFG_CMXFCR_MASK (CMXFCR_FC2|CMXFCR_RF2CS_MSK|CMXFCR_TF2CS_MSK)
# define CFG_CMXFCR_VALUE (CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14)
# define CFG_CPMFCR_RAMTYPE 0
# define CFG_FCC_PSMR (FCC_PSMR_FDE|FCC_PSMR_LPB)
#endif /* CONFIG_ETHER_ON_FCC, CONFIG_ETHER_INDEX */
/* system clock rate (CLKIN) - equal to the 60x and local bus speed */
#define CONFIG_8260_CLKIN 100000000 /* in Hz */
#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
#undef CONFIG_CLOCKS_IN_MHZ
#define CONFIG_PREBOOT \
"echo; " \
"echo Type \"run flash_nfs\" to mount root filesystem over NFS; " \
"echo"
#undef CONFIG_BOOTARGS
#define CONFIG_BOOTCOMMAND \
"bootp; " \
"setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \
"ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; " \
"bootm"
/*-----------------------------------------------------------------------
* I2C/EEPROM/RTC configuration
*/
#define CONFIG_SOFT_I2C /* Software I2C support enabled */
# define CFG_I2C_SPEED 50000
# define CFG_I2C_SLAVE 0xFE
/*
* Software (bit-bang) I2C driver configuration
*/
#define I2C_PORT 3 /* Port A=0, B=1, C=2, D=3 */
#define I2C_ACTIVE (iop->pdir |= 0x00010000)
#define I2C_TRISTATE (iop->pdir &= ~0x00010000)
#define I2C_READ ((iop->pdat & 0x00010000) != 0)
#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00010000; \
else iop->pdat &= ~0x00010000
#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00020000; \
else iop->pdat &= ~0x00020000
#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */
#define CONFIG_RTC_PCF8563
#define CFG_I2C_RTC_ADDR 0x51
#undef CONFIG_WATCHDOG /* watchdog disabled */
/*-----------------------------------------------------------------------
* Disk-On-Chip configuration
*/
#define CFG_MAX_DOC_DEVICE 1 /* Max number of DOC devices */
#define CFG_DOC_SUPPORT_2000
#define CFG_DOC_SUPPORT_MILLENNIUM
/*-----------------------------------------------------------------------
* Miscellaneous configuration options
*/
#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
#undef CFG_LOADS_BAUD_CHANGE /* don't allow baudrate change */
#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT|CONFIG_BOOTP_BOOTFILESIZE)
#ifdef CONFIG_PCI
#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \
CFG_CMD_BEDBUG | \
CFG_CMD_DATE | \
CFG_CMD_DOC | \
CFG_CMD_EEPROM | \
CFG_CMD_I2C | \
CFG_CMD_PCI)
#else /* ! PCI */
#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \
CFG_CMD_BEDBUG | \
CFG_CMD_DATE | \
CFG_CMD_DOC | \
CFG_CMD_EEPROM | \
CFG_CMD_I2C )
#endif /* CONFIG_PCI */
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
/*
* Miscellaneous configurable options
*/
#define CFG_LONGHELP /* undef to save memory */
#define CFG_PROMPT "=> " /* Monitor Command Prompt */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
#else
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#endif
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
#define CFG_MAXARGS 16 /* max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
#define CFG_MEMTEST_START 0x0400000 /* memtest works on */
#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */
#define CFG_LOAD_ADDR 0x100000 /* default load address */
#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
#define CFG_RESET_ADDRESS 0xFFF00100 /* "bad" address */
#define CONFIG_LOOPW
/*
* For booting Linux, the board info and command line data
* have to be in the first 8 MB of memory, since this is
* the maximum mapped by the Linux kernel during initialization.
*/
#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
/*-----------------------------------------------------------------------
* Flash configuration
*/
#define CFG_BOOTROM_BASE 0xFF800000
#define CFG_BOOTROM_SIZE 0x00080000
#define CFG_FLASH_BASE 0xFF000000
#define CFG_FLASH_SIZE 0x00800000
/*-----------------------------------------------------------------------
* FLASH organization
*/
#define CFG_MAX_FLASH_BANKS 2 /* max num of memory banks */
#define CFG_MAX_FLASH_SECT 135 /* max num of sects on one chip */
#define CFG_FLASH_ERASE_TOUT 240000 /* Flash Erase Timeout (in ms) */
#define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (in ms) */
/*-----------------------------------------------------------------------
* Other areas to be mapped
*/
/* CS3: Dual ported SRAM */
#define CFG_DPSRAM_BASE 0x40000000
#define CFG_DPSRAM_SIZE 0x00100000
/* CS4: DiskOnChip */
#define CFG_DOC_BASE 0xF4000000
#define CFG_DOC_SIZE 0x00100000
/* CS5: FDC37C78 controller */
#define CFG_FDC37C78_BASE 0xF1000000
#define CFG_FDC37C78_SIZE 0x00100000
/* CS6: Board configuration registers */
#define CFG_BCRS_BASE 0xF2000000
#define CFG_BCRS_SIZE 0x00010000
/* CS7: VME Extended Access Range */
#define CFG_VMEEAR_BASE 0x60000000
#define CFG_VMEEAR_SIZE 0x01000000
/* CS8: VME Standard Access Range */
#define CFG_VMESAR_BASE 0xFE000000
#define CFG_VMESAR_SIZE 0x01000000
/* CS9: VME Short I/O Access Range */
#define CFG_VMESIOAR_BASE 0xFD000000
#define CFG_VMESIOAR_SIZE 0x01000000
/*-----------------------------------------------------------------------
* Hard Reset Configuration Words
*
* if you change bits in the HRCW, you must also change the CFG_*
* defines for the various registers affected by the HRCW e.g. changing
* HRCW_DPPCxx requires you to also change CFG_SIUMCR.
*/
#if defined(CONFIG_BOOT_ROM)
#define CFG_HRCW_MASTER (HRCW_CIP | HRCW_ISB100 | HRCW_BMS | \
HRCW_BPS01 | HRCW_CS10PC01)
#else
#define CFG_HRCW_MASTER (HRCW_CIP | HRCW_ISB100 | HRCW_BMS | HRCW_CS10PC01)
#endif
/* no slaves so just fill with zeros */
#define CFG_HRCW_SLAVE1 0
#define CFG_HRCW_SLAVE2 0
#define CFG_HRCW_SLAVE3 0
#define CFG_HRCW_SLAVE4 0
#define CFG_HRCW_SLAVE5 0
#define CFG_HRCW_SLAVE6 0
#define CFG_HRCW_SLAVE7 0
/*-----------------------------------------------------------------------
* Internal Memory Mapped Register
*/
#define CFG_IMMR 0xF0000000
/*-----------------------------------------------------------------------
* Definitions for initial stack pointer and data area (in DPRAM)
*/
#define CFG_INIT_RAM_ADDR CFG_IMMR
#define CFG_INIT_RAM_END 0x4000 /* End of used area in DPRAM */
#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data*/
#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
/*-----------------------------------------------------------------------
* Start addresses for the final memory configuration
* (Set up by the startup code)
* Please note that CFG_SDRAM_BASE _must_ start at 0
*
* 60x SDRAM is mapped at CFG_SDRAM_BASE.
*/
#define CFG_SDRAM_BASE 0x00000000
#define CFG_SDRAM_MAX_SIZE 0x08000000 /* max. 128 MB */
#define CFG_MONITOR_BASE TEXT_BASE
#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc()*/
#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
# define CFG_RAMBOOT
#endif
#ifdef CONFIG_PCI
#define CONFIG_PCI_PNP
#define CONFIG_EEPRO100
#define CFG_RX_ETH_BUFFER 8 /* use 8 rx buffer on eepro100 */
#endif
#if 0
/* environment is in Flash */
#define CFG_ENV_IS_IN_FLASH 1
#ifdef CONFIG_BOOT_ROM
# define CFG_ENV_ADDR (CFG_FLASH_BASE+0x70000)
# define CFG_ENV_SIZE 0x10000
# define CFG_ENV_SECT_SIZE 0x10000
#endif
#else
/* environment is in EEPROM */
#define CFG_ENV_IS_IN_EEPROM 1
#define CFG_I2C_EEPROM_ADDR 0x58 /* EEPROM X24C16 */
#define CFG_I2C_EEPROM_ADDR_LEN 1
/* mask of address bits that overflow into the "EEPROM chip address" */
#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x07
#define CFG_EEPROM_PAGE_WRITE_BITS 4
#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */
#define CFG_ENV_OFFSET 512
#define CFG_ENV_SIZE (2048 - 512)
#endif
/*
* Internal Definitions
*
* Boot Flags
*/
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH*/
#define BOOTFLAG_WARM 0x02 /* Software reboot */
/*-----------------------------------------------------------------------
* Cache Configuration
*/
#define CFG_CACHELINE_SIZE 32 /* For MPC8260 CPU */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
#endif
/*-----------------------------------------------------------------------
* HIDx - Hardware Implementation-dependent Registers 2-11
*-----------------------------------------------------------------------
* HID0 also contains cache control - initially enable both caches and
* invalidate contents, then the final state leaves only the instruction
* cache enabled. Note that Power-On and Hard reset invalidate the caches,
* but Soft reset does not.
*
* HID1 has only read-only information - nothing to set.
*/
#define CFG_HID0_INIT (HID0_ICE|HID0_DCE|HID0_ICFI|\
HID0_DCI|HID0_IFEM|HID0_ABE)
#define CFG_HID0_FINAL (HID0_IFEM|HID0_ABE)
#define CFG_HID2 0
/*-----------------------------------------------------------------------
* RMR - Reset Mode Register 5-5
*-----------------------------------------------------------------------
* turn on Checkstop Reset Enable
*/
#define CFG_RMR RMR_CSRE
/*-----------------------------------------------------------------------
* BCR - Bus Configuration 4-25
*-----------------------------------------------------------------------
*/
#define BCR_APD01 0x10000000
#define CFG_BCR (BCR_APD01|BCR_ETM|BCR_LETM) /* 8260 mode */
/*-----------------------------------------------------------------------
* SIUMCR - SIU Module Configuration 4-31
*-----------------------------------------------------------------------
*/
#define CFG_SIUMCR (SIUMCR_BBD|SIUMCR_DPPC00|SIUMCR_APPC10|\
SIUMCR_CS10PC01|SIUMCR_BCTLC10)
/*-----------------------------------------------------------------------
* SYPCR - System Protection Control 4-35
* SYPCR can only be written once after reset!
*-----------------------------------------------------------------------
* Watchdog & Bus Monitor Timer max, 60x Bus Monitor enable
*/
#if defined(CONFIG_WATCHDOG)
#define CFG_SYPCR (SYPCR_SWTC|SYPCR_BMT|SYPCR_PBME|SYPCR_LBME|\
SYPCR_SWRI|SYPCR_SWP|SYPCR_SWE)
#else
#define CFG_SYPCR (SYPCR_SWTC|SYPCR_BMT|SYPCR_PBME|SYPCR_LBME|\
SYPCR_SWRI|SYPCR_SWP)
#endif /* CONFIG_WATCHDOG */
/*-----------------------------------------------------------------------
* TMCNTSC - Time Counter Status and Control 4-40
*-----------------------------------------------------------------------
* Clear once per Second and Alarm Interrupt Status, Set 32KHz timersclk,
* and enable Time Counter
*/
#define CFG_TMCNTSC (TMCNTSC_SEC|TMCNTSC_ALR|TMCNTSC_TCF|TMCNTSC_TCE)
/*-----------------------------------------------------------------------
* PISCR - Periodic Interrupt Status and Control 4-42
*-----------------------------------------------------------------------
* Clear Periodic Interrupt Status, Set 32KHz timersclk, and enable
* Periodic timer
*/
#define CFG_PISCR (PISCR_PS|PISCR_PTF|PISCR_PTE)
/*-----------------------------------------------------------------------
* SCCR - System Clock Control 9-8
*-----------------------------------------------------------------------
* Ensure DFBRG is Divide by 16
*/
#define CFG_SCCR SCCR_DFBRG01
/*-----------------------------------------------------------------------
* RCCR - RISC Controller Configuration 13-7
*-----------------------------------------------------------------------
*/
#define CFG_RCCR 0
#define CFG_MIN_AM_MASK 0xC0000000
/*
* we use the same values for 32 MB and 128 MB SDRAM
* refresh rate = 7.68 uS (100 MHz Bus Clock)
*/
/*-----------------------------------------------------------------------
* MPTPR - Memory Refresh Timer Prescaler Register 10-18
*-----------------------------------------------------------------------
*/
#define CFG_MPTPR 0x2000
/*-----------------------------------------------------------------------
* PSRT - Refresh Timer Register 10-16
*-----------------------------------------------------------------------
*/
#define CFG_PSRT 0x16
/*-----------------------------------------------------------------------
* PSRT - SDRAM Mode Register 10-10
*-----------------------------------------------------------------------
*/
/* SDRAM initialization values for 8-column chips
*/
#define CFG_OR2_8COL (CFG_MIN_AM_MASK |\
ORxS_BPD_4 |\
ORxS_ROWST_PBI0_A9 |\
ORxS_NUMR_12)
#define CFG_PSDMR_8COL (PSDMR_SDAM_A13_IS_A5 |\
PSDMR_BSMA_A14_A16 |\
PSDMR_SDA10_PBI0_A10 |\
PSDMR_RFRC_7_CLK |\
PSDMR_PRETOACT_2W |\
PSDMR_ACTTORW_2W |\
PSDMR_LDOTOPRE_1C |\
PSDMR_WRC_1C |\
PSDMR_CL_2)
/* SDRAM initialization values for 9-column chips
*/
#define CFG_OR2_9COL (CFG_MIN_AM_MASK |\
ORxS_BPD_4 |\
ORxS_ROWST_PBI0_A7 |\
ORxS_NUMR_13)
#define CFG_PSDMR_9COL (PSDMR_SDAM_A14_IS_A5 |\
PSDMR_BSMA_A13_A15 |\
PSDMR_SDA10_PBI0_A9 |\
PSDMR_RFRC_7_CLK |\
PSDMR_PRETOACT_2W |\
PSDMR_ACTTORW_2W |\
PSDMR_LDOTOPRE_1C |\
PSDMR_WRC_1C |\
PSDMR_CL_2)
/*
* Init Memory Controller:
*
* Bank Bus Machine PortSz Device
* ---- --- ------- ------ ------
* 0 60x GPCM 8 bit Boot ROM
* 1 60x GPCM 64 bit FLASH
* 2 60x SDRAM 64 bit SDRAM
*
*/
#define CFG_MRS_OFFS 0x00000000
#ifdef CONFIG_BOOT_ROM
/* Bank 0 - Boot ROM
*/
#define CFG_BR0_PRELIM ((CFG_BOOTROM_BASE & BRx_BA_MSK)|\
BRx_PS_8 |\
BRx_MS_GPCM_P |\
BRx_V)
#define CFG_OR0_PRELIM (P2SZ_TO_AM(CFG_BOOTROM_SIZE) |\
ORxG_CSNT |\
ORxG_ACS_DIV1 |\
ORxG_SCY_5_CLK |\
ORxU_EHTR_8IDLE)
/* Bank 1 - FLASH
*/
#define CFG_BR1_PRELIM ((CFG_FLASH_BASE & BRx_BA_MSK) |\
BRx_PS_64 |\
BRx_MS_GPCM_P |\
BRx_V)
#define CFG_OR1_PRELIM (P2SZ_TO_AM(CFG_FLASH_SIZE) |\
ORxG_CSNT |\
ORxG_ACS_DIV1 |\
ORxG_SCY_5_CLK |\
ORxU_EHTR_8IDLE)
#else /* CONFIG_BOOT_ROM */
/* Bank 0 - FLASH
*/
#define CFG_BR0_PRELIM ((CFG_FLASH_BASE & BRx_BA_MSK) |\
BRx_PS_64 |\
BRx_MS_GPCM_P |\
BRx_V)
#define CFG_OR0_PRELIM (P2SZ_TO_AM(CFG_FLASH_SIZE) |\
ORxG_CSNT |\
ORxG_ACS_DIV1 |\
ORxG_SCY_5_CLK |\
ORxU_EHTR_8IDLE)
/* Bank 1 - Boot ROM
*/
#define CFG_BR1_PRELIM ((CFG_BOOTROM_BASE & BRx_BA_MSK)|\
BRx_PS_8 |\
BRx_MS_GPCM_P |\
BRx_V)
#define CFG_OR1_PRELIM (P2SZ_TO_AM(CFG_BOOTROM_SIZE) |\
ORxG_CSNT |\
ORxG_ACS_DIV1 |\
ORxG_SCY_5_CLK |\
ORxU_EHTR_8IDLE)
#endif /* CONFIG_BOOT_ROM */
/* Bank 2 - 60x bus SDRAM
*/
#ifndef CFG_RAMBOOT
#define CFG_BR2_PRELIM ((CFG_SDRAM_BASE & BRx_BA_MSK) |\
BRx_PS_64 |\
BRx_MS_SDRAM_P |\
BRx_V)
#define CFG_OR2_PRELIM CFG_OR2_9COL
#define CFG_PSDMR CFG_PSDMR_9COL
#endif /* CFG_RAMBOOT */
/* Bank 3 - Dual Ported SRAM
*/
#define CFG_BR3_PRELIM ((CFG_DPSRAM_BASE & BRx_BA_MSK) |\
BRx_PS_16 |\
BRx_MS_GPCM_P |\
BRx_V)
#define CFG_OR3_PRELIM (P2SZ_TO_AM(CFG_DPSRAM_SIZE) |\
ORxG_CSNT |\
ORxG_ACS_DIV1 |\
ORxG_SCY_7_CLK |\
ORxG_SETA)
/* Bank 4 - DiskOnChip
*/
#define CFG_BR4_PRELIM ((CFG_DOC_BASE & BRx_BA_MSK) |\
BRx_PS_8 |\
BRx_MS_GPCM_P |\
BRx_V)
#define CFG_OR4_PRELIM (P2SZ_TO_AM(CFG_DOC_SIZE) |\
ORxG_CSNT |\
ORxG_ACS_DIV2 |\
ORxG_SCY_9_CLK |\
ORxU_EHTR_8IDLE)
/* Bank 5 - FDC37C78 controller
*/
#define CFG_BR5_PRELIM ((CFG_FDC37C78_BASE & BRx_BA_MSK) |\
BRx_PS_8 |\
BRx_MS_GPCM_P |\
BRx_V)
#define CFG_OR5_PRELIM (P2SZ_TO_AM(CFG_FDC37C78_SIZE) |\
ORxG_ACS_DIV2 |\
ORxG_SCY_10_CLK |\
ORxU_EHTR_8IDLE)
/* Bank 6 - Board control registers
*/
#define CFG_BR6_PRELIM ((CFG_BCRS_BASE & BRx_BA_MSK) |\
BRx_PS_8 |\
BRx_MS_GPCM_P |\
BRx_V)
#define CFG_OR6_PRELIM (P2SZ_TO_AM(CFG_BCRS_SIZE) |\
ORxG_CSNT |\
ORxG_SCY_7_CLK)
/* Bank 7 - VME Extended Access Range
*/
#define CFG_BR7_PRELIM ((CFG_VMEEAR_BASE & BRx_BA_MSK) |\
BRx_PS_32 |\
BRx_MS_GPCM_P |\
BRx_V)
#define CFG_OR7_PRELIM (P2SZ_TO_AM(CFG_VMEEAR_SIZE) |\
ORxG_CSNT |\
ORxG_ACS_DIV1 |\
ORxG_SCY_7_CLK |\
ORxG_SETA)
/* Bank 8 - VME Standard Access Range
*/
#define CFG_BR8_PRELIM ((CFG_VMESAR_BASE & BRx_BA_MSK) |\
BRx_PS_16 |\
BRx_MS_GPCM_P |\
BRx_V)
#define CFG_OR8_PRELIM (P2SZ_TO_AM(CFG_VMESAR_SIZE) |\
ORxG_CSNT |\
ORxG_ACS_DIV1 |\
ORxG_SCY_7_CLK |\
ORxG_SETA)
/* Bank 9 - VME Short I/O Access Range
*/
#define CFG_BR9_PRELIM ((CFG_VMESIOAR_BASE & BRx_BA_MSK) |\
BRx_PS_16 |\
BRx_MS_GPCM_P |\
BRx_V)
#define CFG_OR9_PRELIM (P2SZ_TO_AM(CFG_VMESIOAR_SIZE) |\
ORxG_CSNT |\
ORxG_ACS_DIV1 |\
ORxG_SCY_7_CLK |\
ORxG_SETA)
#endif /* __CONFIG_H */

430
include/configs/PM854.h Normal file
View file

@ -0,0 +1,430 @@
/*
* Copyright 2004 Freescale Semiconductor.
* (C) Copyright 2002,2003 Motorola,Inc.
* Xianghua Xiao <X.Xiao@motorola.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
*/
/*
* pm854 board configuration file
*
* Please refer to doc/README.mpc85xx for more info.
*
* Make sure you change the MAC address and other network params first,
* search for CONFIG_ETHADDR, CONFIG_SERVERIP, etc in this file.
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/* High Level Configuration Options */
#define CONFIG_BOOKE 1 /* BOOKE */
#define CONFIG_E500 1 /* BOOKE e500 family */
#define CONFIG_MPC85xx 1 /* MPC8540/MPC8560 */
#define CONFIG_MPC8540 1 /* MPC8540 specific */
#define CONFIG_PM854 1 /* PM854 board specific */
#define CONFIG_PCI
#define CONFIG_TSEC_ENET /* tsec ethernet support */
#define CONFIG_ENV_OVERWRITE
#undef CONFIG_SPD_EEPROM /* do not use SPD EEPROM for DDR setup*/
#define CONFIG_DDR_ECC /* only for ECC DDR module */
#define CONFIG_DDR_DLL /* possible DLL fix needed */
#define CONFIG_DDR_2T_TIMING /* Sets the 2T timing bit */
/*
* sysclk for MPC85xx
*
* Two valid values are:
* 33000000
* 66000000
*
* Most PCI cards are still 33Mhz, so in the presence of PCI, 33MHz
* is likely the desired value here, so that is now the default.
* The board, however, can run at 66MHz. In any event, this value
* must match the settings of some switches. Details can be found
* in the README.mpc85xxads.
*/
#ifndef CONFIG_SYS_CLK_FREQ
#define CONFIG_SYS_CLK_FREQ 66000000
#endif
/*
* These can be toggled for performance analysis, otherwise use default.
*/
#define CONFIG_L2_CACHE /* toggle L2 cache */
#define CONFIG_BTB /* toggle branch predition */
#define CONFIG_ADDR_STREAMING /* toggle addr streaming */
#define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */
#undef CFG_DRAM_TEST /* memory test, takes time */
#define CFG_MEMTEST_START 0x00200000 /* memtest region */
#define CFG_MEMTEST_END 0x00400000
/*
* Base addresses -- Note these are effective addresses where the
* actual resources get mapped (not physical addresses)
*/
#define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */
#define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */
#define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */
/*
* DDR Setup
*/
#define CFG_DDR_SDRAM_BASE 0x00000000 /* DDR is system memory*/
#define CFG_SDRAM_BASE CFG_DDR_SDRAM_BASE
#if defined(CONFIG_SPD_EEPROM)
/*
* Determine DDR configuration from I2C interface.
*/
#define SPD_EEPROM_ADDRESS 0x51 /* DDR DIMM */
#else
/*
* Manually set up DDR parameters
*/
#define CFG_SDRAM_SIZE 256 /* DDR is 256 MB */
#define CFG_DDR_CS0_BNDS 0x0000000f /* 0-256MB */
#define CFG_DDR_CS0_CONFIG 0x80000102
#define CFG_DDR_TIMING_1 0x47444321
#define CFG_DDR_TIMING_2 0x00000800 /* P9-45,may need tuning */
#define CFG_DDR_CONTROL 0xc2008000 /* unbuffered,no DYN_PWR */
#define CFG_DDR_MODE 0x00000062 /* DLL,normal,seq,4/2.5 */
#define CFG_DDR_INTERVAL 0x045b0100 /* autocharge,no open page */
#endif
/*
* SDRAM on the Local Bus
*/
#define CFG_LBC_SDRAM_BASE 0xf0000000 /* Localbus SDRAM */
#define CFG_LBC_SDRAM_SIZE 0 /* LBC SDRAM is 0 MB */
#define CFG_FLASH_BASE 0xfe000000 /* start of 32 MB FLASH */
#define CFG_BR0_PRELIM 0xfe001801 /* port size 32bit */
#define CFG_OR0_PRELIM 0xfe006f67 /* 32 MB Flash */
#define CFG_MAX_FLASH_BANKS 1 /* number of banks */
#define CFG_MAX_FLASH_SECT 128 /* sectors per device */
#undef CFG_FLASH_CHECKSUM
#define CFG_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */
#define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */
#define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */
#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
#define CFG_RAMBOOT
#else
#undef CFG_RAMBOOT
#endif
#undef CONFIG_CLOCKS_IN_MHZ
/*
* Local Bus Definitions
*/
#define CFG_LBC_LCRR 0x00030004 /* LB clock ratio reg */
#define CFG_LBC_LBCR 0x00000000 /* LB config reg */
#define CFG_LBC_LSRT 0x20000000 /* LB sdram refresh timer */
#define CFG_LBC_MRTPR 0x20000000 /* LB refresh timer prescal*/
#define CONFIG_L1_INIT_RAM
#define CFG_INIT_RAM_LOCK 1
#define CFG_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */
#define CFG_INIT_RAM_END 0x4000 /* End of used area in RAM */
#define CFG_GBL_DATA_SIZE 128 /* num bytes initial data */
#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
#define CFG_MONITOR_LEN (512 * 1024) /* Reserve 512 kB for Mon */
#define CFG_MALLOC_LEN (128 * 1024) /* Reserved for malloc */
/* Serial Port */
#define CONFIG_CONS_INDEX 1
#undef CONFIG_SERIAL_SOFTWARE_FIFO
#define CFG_NS16550
#define CFG_NS16550_SERIAL
#define CFG_NS16550_REG_SIZE 1
#define CFG_NS16550_CLK get_bus_freq(0)
#define CFG_BAUDRATE_TABLE \
{300, 600, 1200, 2400, 4800, 9600, 19200, 38400,115200}
#define CFG_NS16550_COM1 (CFG_CCSRBAR+0x4500)
#define CFG_NS16550_COM2 (CFG_CCSRBAR+0x4600)
/* Use the HUSH parser */
#define CFG_HUSH_PARSER
#ifdef CFG_HUSH_PARSER
#define CFG_PROMPT_HUSH_PS2 "> "
#endif
/* I2C */
#define CONFIG_HARD_I2C /* I2C with hardware support*/
#undef CONFIG_SOFT_I2C /* I2C bit-banged */
#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
#define CFG_I2C_SLAVE 0x7F
#define CFG_I2C_NOPROBES {0x69} /* Don't probe these addrs */
/*
* EEPROM configuration
*/
#define CFG_I2C_EEPROM_ADDR 0x58
#define CFG_I2C_EEPROM_ADDR_LEN 1
#define CFG_EEPROM_PAGE_WRITE_BITS 4
#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10
/*
* RTC configuration
*/
#define CONFIG_RTC_PCF8563
#define CFG_I2C_RTC_ADDR 0x51
/* RapidIO MMU */
#define CFG_RIO_MEM_BASE 0xc0000000 /* base address */
#define CFG_RIO_MEM_PHYS CFG_RIO_MEM_BASE
#define CFG_RIO_MEM_SIZE 0x20000000 /* 128M */
/*
* General PCI
* Addresses are mapped 1-1.
*/
#define CFG_PCI1_MEM_BASE 0x80000000
#define CFG_PCI1_MEM_PHYS CFG_PCI1_MEM_BASE
#define CFG_PCI1_MEM_SIZE 0x20000000 /* 512M */
#define CFG_PCI1_IO_BASE 0xe2000000
#define CFG_PCI1_IO_PHYS CFG_PCI1_IO_BASE
#define CFG_PCI1_IO_SIZE 0x1000000 /* 16M */
#if defined(CONFIG_PCI)
#define CONFIG_NET_MULTI
#define CONFIG_PCI_PNP /* do pci plug-and-play */
#undef CONFIG_EEPRO100
#undef CONFIG_TULIP
#if !defined(CONFIG_PCI_PNP)
#define PCI_ENET0_IOADDR 0xe0000000
#define PCI_ENET0_MEMADDR 0xe0000000
#define PCI_IDSEL_NUMBER 0x0c /* slot0->3(IDSEL)=12->15 */
#endif
#undef CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */
#define CFG_PCI_SUBSYS_VENDORID 0x1057 /* Motorola */
#endif /* CONFIG_PCI */
#if defined(CONFIG_TSEC_ENET)
#ifndef CONFIG_NET_MULTI
#define CONFIG_NET_MULTI 1
#endif
#define CONFIG_MII 1 /* MII PHY management */
#define CONFIG_MPC85XX_TSEC1 1
#define CONFIG_MPC85XX_TSEC2 1
#define TSEC1_PHY_ADDR 2
#define TSEC2_PHY_ADDR 3
#define TSEC1_PHYIDX 0
#define TSEC2_PHYIDX 0
#define CONFIG_MPC85XX_FEC 1
#define FEC_PHY_ADDR 1
#define FEC_PHYIDX 0
#define CONFIG_ETHPRIME "MOTO ENET0"
#define CONFIG_HAS_ETH1 1
#define CONFIG_HAS_ETH2 1
#endif /* CONFIG_TSEC_ENET */
/*
* Environment
*/
#ifndef CFG_RAMBOOT
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_ADDR (CFG_MONITOR_BASE - 0x80000)
#define CFG_ENV_SECT_SIZE 0x40000 /* 256K(one sector) for env */
#define CFG_ENV_SIZE 0x2000
#else
#define CFG_NO_FLASH 1 /* Flash is not usable now */
#define CFG_ENV_IS_NOWHERE 1 /* Store ENV in memory only */
#define CFG_ENV_ADDR (CFG_MONITOR_BASE - 0x1000)
#define CFG_ENV_SIZE 0x2000
#endif
#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */
#if defined(CFG_RAMBOOT)
#if defined(CONFIG_PCI)
#define CONFIG_COMMANDS ((CONFIG_CMD_DFL \
| CFG_CMD_PING \
| CFG_CMD_PCI \
| CFG_CMD_I2C) \
& \
~(CFG_CMD_ENV \
| CFG_CMD_LOADS))
#else
#define CONFIG_COMMANDS ((CONFIG_CMD_DFL \
| CFG_CMD_PING \
| CFG_CMD_I2C) \
& \
~(CFG_CMD_ENV \
| CFG_CMD_LOADS))
#endif
#else
#if defined(CONFIG_PCI)
#define CONFIG_COMMANDS (CONFIG_CMD_DFL \
| CFG_CMD_EEPROM \
| CFG_CMD_DATE \
| CFG_CMD_PCI \
| CFG_CMD_PING \
| CFG_CMD_I2C)
#else
#define CONFIG_COMMANDS (CONFIG_CMD_DFL \
| CFG_CMD_EEPROM \
| CFG_CMD_DATE \
| CFG_CMD_PING \
| CFG_CMD_I2C)
#endif
#endif
#include <cmd_confdefs.h>
#undef CONFIG_WATCHDOG /* watchdog disabled */
/*
* Miscellaneous configurable options
*/
#define CFG_LONGHELP /* undef to save memory */
#define CFG_LOAD_ADDR 0x2000000 /* default load address */
#define CFG_PROMPT "=> " /* Monitor Command Prompt */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
#else
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#endif
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
#define CFG_MAXARGS 16 /* max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
#define CFG_HZ 1000 /* decrementer freq: 1ms ticks */
#define CONFIG_LOOPW
/*
* For booting Linux, the board info and command line data
* have to be in the first 8 MB of memory, since this is
* the maximum mapped by the Linux kernel during initialization.
*/
#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux*/
/* Cache Configuration */
#define CFG_DCACHE_SIZE 32768
#define CFG_CACHELINE_SIZE 32
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CACHELINE_SHIFT 5 /*log base 2 of the above value*/
#endif
/*
* Internal Definitions
*
* Boot Flags
*/
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
#define BOOTFLAG_WARM 0x02 /* Software reboot */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */
#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */
#endif
/*
* Environment Configuration
*/
/* The mac addresses for all ethernet interface */
#if defined(CONFIG_TSEC_ENET)
#define CONFIG_ETHADDR 00:40:42:01:00:00
#define CONFIG_ETH1ADDR 00:40:42:01:00:01
#define CONFIG_ETH2ADDR 00:40:42:01:00:02
#endif
#define CONFIG_IPADDR 192.168.0.103
#define CONFIG_HOSTNAME PM854
#define CONFIG_ROOTPATH /opt/eldk30/ppc_82xx
#define CONFIG_BOOTFILE uImage
#define CONFIG_SERVERIP 192.168.0.54
#define CONFIG_GATEWAYIP 192.168.0.1
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_LOADADDR 200000 /* default location for tftp and bootm */
#define CONFIG_BOOTDELAY 5 /* -1 disables auto-boot */
#undef CONFIG_BOOTARGS /* the boot command will set bootargs */
#define CONFIG_BAUDRATE 9600
#define CONFIG_EXTRA_ENV_SETTINGS \
"netdev=eth0\0" \
"consoledev=ttyS0\0" \
"ramdiskaddr=400000\0" \
"ramdiskfile=uRamdisk\0"
#define CONFIG_NFSBOOTCOMMAND \
"setenv bootargs root=/dev/nfs rw " \
"nfsroot=$serverip:$rootpath " \
"ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \
"console=$consoledev,$baudrate $othbootargs;" \
"tftp $loadaddr $bootfile;" \
"bootm $loadaddr"
#define CONFIG_RAMBOOTCOMMAND \
"setenv bootargs root=/dev/ram rw " \
"console=$consoledev,$baudrate $othbootargs;" \
"tftp $ramdiskaddr $ramdiskfile;" \
"tftp $loadaddr $bootfile;" \
"bootm $loadaddr $ramdiskaddr"
#define CONFIG_BOOTCOMMAND CONFIG_NFSBOOTCOMMAND
#endif /* __CONFIG_H */

View file

@ -122,6 +122,7 @@ struct nand_chip {
uint oobblock; /* Size of OOB blocks (e.g. 512) */
uint oobsize; /* Amount of OOB data per block (e.g. 16) */
uint eccsize;
int bus16;
};
/*
@ -165,6 +166,7 @@ struct nand_flash_dev {
char page256;
char pageadrlen;
unsigned long erasesize;
int bus16;
};
/*

View file

@ -29,24 +29,26 @@
#define __LINUX_MTD_NAND_IDS_H
static struct nand_flash_dev nand_flash_ids[] = {
{"Toshiba TC5816BDC", NAND_MFR_TOSHIBA, 0x64, 21, 1, 2, 0x1000},
{"Toshiba TC5832DC", NAND_MFR_TOSHIBA, 0x6b, 22, 0, 2, 0x2000},
{"Toshiba TH58V128DC", NAND_MFR_TOSHIBA, 0x73, 24, 0, 2, 0x4000},
{"Toshiba TC58256FT/DC", NAND_MFR_TOSHIBA, 0x75, 25, 0, 2, 0x4000},
{"Toshiba TH58512FT", NAND_MFR_TOSHIBA, 0x76, 26, 0, 3, 0x4000},
{"Toshiba TC58V32DC", NAND_MFR_TOSHIBA, 0xe5, 22, 0, 2, 0x2000},
{"Toshiba TC58V64AFT/DC", NAND_MFR_TOSHIBA, 0xe6, 23, 0, 2, 0x2000},
{"Toshiba TC58V16BDC", NAND_MFR_TOSHIBA, 0xea, 21, 1, 2, 0x1000},
{"Toshiba TH58100FT", NAND_MFR_TOSHIBA, 0x79, 27, 0, 3, 0x4000},
{"Samsung KM29N16000", NAND_MFR_SAMSUNG, 0x64, 21, 1, 2, 0x1000},
{"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0x6b, 22, 0, 2, 0x2000},
{"Samsung KM29U128T", NAND_MFR_SAMSUNG, 0x73, 24, 0, 2, 0x4000},
{"Samsung KM29U256T", NAND_MFR_SAMSUNG, 0x75, 25, 0, 2, 0x4000},
{"Samsung unknown 64Mb", NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000},
{"Samsung KM29W32000", NAND_MFR_SAMSUNG, 0xe3, 22, 0, 2, 0x2000},
{"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0xe5, 22, 0, 2, 0x2000},
{"Samsung KM29U64000", NAND_MFR_SAMSUNG, 0xe6, 23, 0, 2, 0x2000},
{"Samsung KM29W16000", NAND_MFR_SAMSUNG, 0xea, 21, 1, 2, 0x1000},
{"Toshiba TC5816BDC", NAND_MFR_TOSHIBA, 0x64, 21, 1, 2, 0x1000, 0},
{"Toshiba TC5832DC", NAND_MFR_TOSHIBA, 0x6b, 22, 0, 2, 0x2000, 0},
{"Toshiba TH58V128DC", NAND_MFR_TOSHIBA, 0x73, 24, 0, 2, 0x4000, 0},
{"Toshiba TC58256FT/DC", NAND_MFR_TOSHIBA, 0x75, 25, 0, 2, 0x4000, 0},
{"Toshiba TH58512FT", NAND_MFR_TOSHIBA, 0x76, 26, 0, 3, 0x4000, 0},
{"Toshiba TC58V32DC", NAND_MFR_TOSHIBA, 0xe5, 22, 0, 2, 0x2000, 0},
{"Toshiba TC58V64AFT/DC", NAND_MFR_TOSHIBA, 0xe6, 23, 0, 2, 0x2000, 0},
{"Toshiba TC58V16BDC", NAND_MFR_TOSHIBA, 0xea, 21, 1, 2, 0x1000, 0},
{"Toshiba TH58100FT", NAND_MFR_TOSHIBA, 0x79, 27, 0, 3, 0x4000, 0},
{"Samsung KM29N16000", NAND_MFR_SAMSUNG, 0x64, 21, 1, 2, 0x1000, 0},
{"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0x6b, 22, 0, 2, 0x2000, 0},
{"Samsung KM29U128T", NAND_MFR_SAMSUNG, 0x73, 24, 0, 2, 0x4000, 0},
{"Samsung KM29U256T", NAND_MFR_SAMSUNG, 0x75, 25, 0, 2, 0x4000, 0},
{"Samsung unknown 64Mb", NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0},
{"Samsung KM29W32000", NAND_MFR_SAMSUNG, 0xe3, 22, 0, 2, 0x2000, 0},
{"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0xe5, 22, 0, 2, 0x2000, 0},
{"Samsung KM29U64000", NAND_MFR_SAMSUNG, 0xe6, 23, 0, 2, 0x2000, 0},
{"Samsung KM29W16000", NAND_MFR_SAMSUNG, 0xea, 21, 1, 2, 0x1000, 0},
{"Samsung K9F5616Q0C", NAND_MFR_SAMSUNG, 0x45, 25, 0, 2, 0x4000, 1},
{"Samsung K9K1216Q0C", NAND_MFR_SAMSUNG, 0x46, 26, 0, 3, 0x4000, 1},
{NULL,}
};