Merge with /home/wd/git/u-boot/testing-NAND/ to add new NAND handling.
This commit is contained in:
		
						commit
						038ccac511
					
				|  | @ -2,6 +2,11 @@ | ||||||
| Changes since U-Boot 1.1.4: | Changes since U-Boot 1.1.4: | ||||||
| ====================================================================== | ====================================================================== | ||||||
| 
 | 
 | ||||||
|  | * Merge the new NAND code (testing-NAND brach) | ||||||
|  | 
 | ||||||
|  |   Rewrite of NAND code based on what is in 2.6.12 Linux kernel | ||||||
|  |   Patch by Ladislav Michl, 29 Jun 2005 | ||||||
|  | 
 | ||||||
| * Update default environment for INKA4x00 board. | * Update default environment for INKA4x00 board. | ||||||
| 
 | 
 | ||||||
| * Cleanup U-Boot boot messages on ARM. | * Cleanup U-Boot boot messages on ARM. | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										12
									
								
								Makefile
								
								
								
								
							|  | @ -121,6 +121,7 @@ LIBS += drivers/libdrivers.a | ||||||
| LIBS += drivers/sk98lin/libsk98lin.a | LIBS += drivers/sk98lin/libsk98lin.a | ||||||
| LIBS += post/libpost.a post/cpu/libcpu.a | LIBS += post/libpost.a post/cpu/libcpu.a | ||||||
| LIBS += common/libcommon.a | LIBS += common/libcommon.a | ||||||
|  | LIBS += $(BOARDLIBS) | ||||||
| .PHONY : $(LIBS) | .PHONY : $(LIBS) | ||||||
| 
 | 
 | ||||||
| # Add GCC lib
 | # Add GCC lib
 | ||||||
|  | @ -1459,6 +1460,17 @@ mx1ads_config	:	unconfig | ||||||
| mx1fs2_config	:	unconfig | mx1fs2_config	:	unconfig | ||||||
| 	@./mkconfig $(@:_config=) arm arm920t mx1fs2 NULL imx | 	@./mkconfig $(@:_config=) arm arm920t mx1fs2 NULL imx | ||||||
| 
 | 
 | ||||||
|  | netstar_32_config	\ | ||||||
|  | netstar_config:		unconfig | ||||||
|  | 	@if [ "$(findstring _32_,$@)" ] ; then \
 | ||||||
|  | 		echo "... 32MB SDRAM" ; \
 | ||||||
|  | 		echo "#define PHYS_SDRAM_1_SIZE SZ_32M" >>include/config.h ; \
 | ||||||
|  | 	else \
 | ||||||
|  | 		echo "... 64MB SDRAM" ; \
 | ||||||
|  | 		echo "#define PHYS_SDRAM_1_SIZE SZ_64M" >>include/config.h ; \
 | ||||||
|  | 	fi | ||||||
|  | 	@./mkconfig -a netstar arm arm925t netstar | ||||||
|  | 
 | ||||||
| omap1510inn_config :	unconfig | omap1510inn_config :	unconfig | ||||||
| 	@./mkconfig $(@:_config=) arm arm925t omap1510inn | 	@./mkconfig $(@:_config=) arm arm925t omap1510inn | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ include $(TOPDIR)/config.mk | ||||||
| 
 | 
 | ||||||
| LIB	= lib$(BOARD).a | LIB	= lib$(BOARD).a | ||||||
| 
 | 
 | ||||||
| OBJS	= $(BOARD).o flash.o | OBJS	= $(BOARD).o flash.o nand.o | ||||||
| 
 | 
 | ||||||
| $(LIB):	$(OBJS) $(SOBJS) | $(LIB):	$(OBJS) $(SOBJS) | ||||||
| 	$(AR) crv $@ $^ | 	$(AR) crv $@ $^ | ||||||
|  |  | ||||||
|  | @ -238,33 +238,6 @@ int testdram (void) | ||||||
| 
 | 
 | ||||||
| /* ------------------------------------------------------------------------- */ | /* ------------------------------------------------------------------------- */ | ||||||
| 
 | 
 | ||||||
| #if (CONFIG_COMMANDS & CFG_CMD_NAND) |  | ||||||
| extern ulong |  | ||||||
| nand_probe(ulong physadr); |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| nand_init(void) |  | ||||||
| { |  | ||||||
| 	ulong totlen = 0; |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
| 	The HI model is equipped with a large block NAND chip not supported yet |  | ||||||
| 	by U-Boot |  | ||||||
|     (CONFIG_PPCHAMELEON_MODULE_MODEL == CONFIG_PPCHAMELEON_MODULE_HI) |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| #if (CONFIG_PPCHAMELEON_MODULE_MODEL == CONFIG_PPCHAMELEON_MODULE_ME) |  | ||||||
| 	debug ("Probing at 0x%.8x\n", CFG_NAND0_BASE); |  | ||||||
| 	totlen += nand_probe (CFG_NAND0_BASE); |  | ||||||
| #endif	/* CONFIG_PPCHAMELEON_MODULE_ME, CONFIG_PPCHAMELEON_MODULE_HI */ |  | ||||||
| 
 |  | ||||||
| 	debug ("Probing at 0x%.8x\n", CFG_NAND1_BASE); |  | ||||||
| 	totlen += nand_probe (CFG_NAND1_BASE); |  | ||||||
| 
 |  | ||||||
| 	printf ("%3lu MB\n", totlen >>20); |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #ifdef CONFIG_CFB_CONSOLE | #ifdef CONFIG_CFB_CONSOLE | ||||||
| # ifdef CONFIG_CONSOLE_EXTRA_INFO | # ifdef CONFIG_CONSOLE_EXTRA_INFO | ||||||
| # include <video_fb.h> | # include <video_fb.h> | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| #
 | #
 | ||||||
| # (C) Copyright 2000
 | # (C) Copyright 2000, 2006
 | ||||||
| # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 | # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 | ||||||
| #
 | #
 | ||||||
| # See file CREDITS for list of people who contributed to this
 | # See file CREDITS for list of people who contributed to this
 | ||||||
|  | @ -22,7 +22,10 @@ | ||||||
| #
 | #
 | ||||||
| 
 | 
 | ||||||
| # Reserve 256 kB for Monitor
 | # Reserve 256 kB for Monitor
 | ||||||
| TEXT_BASE = 0xFFFC0000 | #TEXT_BASE = 0xFFFC0000
 | ||||||
| 
 | 
 | ||||||
| # Reserve 320 kB for Monitor
 | # Reserve 320 kB for Monitor
 | ||||||
| #TEXT_BASE = 0xFFFB0000
 | TEXT_BASE = 0xFFFB0000 | ||||||
|  | 
 | ||||||
|  | # Compile the new NAND code (needed iff #ifdef CONFIG_NEW_NAND_CODE)
 | ||||||
|  | BOARDLIBS = drivers/nand/libnand.a | ||||||
|  |  | ||||||
|  | @ -0,0 +1,147 @@ | ||||||
|  | /*
 | ||||||
|  |  * (C) Copyright 2006 DENX Software Engineering | ||||||
|  |  * | ||||||
|  |  * 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 (CONFIG_COMMANDS & CFG_CMD_NAND) | ||||||
|  | #ifdef CONFIG_NEW_NAND_CODE | ||||||
|  | /* new NAND handling */ | ||||||
|  | 
 | ||||||
|  | #include <nand.h> | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * hardware specific access to control-lines | ||||||
|  |  * function borrowed from Linux 2.6 (drivers/mtd/nand/ppchameleonevb.c) | ||||||
|  |  */ | ||||||
|  | static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd) | ||||||
|  | { | ||||||
|  | 	struct nand_chip *this = mtdinfo->priv; | ||||||
|  | 	ulong base = (ulong) this->IO_ADDR_W; | ||||||
|  | 
 | ||||||
|  | 	switch(cmd) { | ||||||
|  | 	case NAND_CTL_SETCLE: | ||||||
|  | 		MACRO_NAND_CTL_SETCLE((unsigned long)base); | ||||||
|  | 		break; | ||||||
|  | 	case NAND_CTL_CLRCLE: | ||||||
|  | 		MACRO_NAND_CTL_CLRCLE((unsigned long)base); | ||||||
|  | 		break; | ||||||
|  | 	case NAND_CTL_SETALE: | ||||||
|  | 		MACRO_NAND_CTL_SETALE((unsigned long)base); | ||||||
|  | 		break; | ||||||
|  | 	case NAND_CTL_CLRALE: | ||||||
|  | 		MACRO_NAND_CTL_CLRALE((unsigned long)base); | ||||||
|  | 		break; | ||||||
|  | 	case NAND_CTL_SETNCE: | ||||||
|  | 		MACRO_NAND_ENABLE_CE((unsigned long)base); | ||||||
|  | 		break; | ||||||
|  | 	case NAND_CTL_CLRNCE: | ||||||
|  | 		MACRO_NAND_DISABLE_CE((unsigned long)base); | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * read device ready pin | ||||||
|  |  * function +/- borrowed from Linux 2.6 (drivers/mtd/nand/ppchameleonevb.c) | ||||||
|  |  */ | ||||||
|  | static int ppchameleonevb_device_ready(struct mtd_info *mtdinfo) | ||||||
|  | { | ||||||
|  | 	struct nand_chip *this = mtdinfo->priv; | ||||||
|  | 	ulong rb_gpio_pin; | ||||||
|  | 
 | ||||||
|  | 	/* use the base addr to find out which chip are we dealing with */ | ||||||
|  | 	switch((ulong) this->IO_ADDR_W) { | ||||||
|  | 	case CFG_NAND0_BASE: | ||||||
|  | 		rb_gpio_pin = CFG_NAND0_RDY; | ||||||
|  | 		break; | ||||||
|  | 	case CFG_NAND1_BASE: | ||||||
|  | 		rb_gpio_pin = CFG_NAND1_RDY; | ||||||
|  | 		break; | ||||||
|  | 	default: /* this should never happen */ | ||||||
|  | 		return 0; | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  |         if (in32(GPIO0_IR) & rb_gpio_pin) | ||||||
|  | 		return 1; | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Board-specific NAND initialization. The following members of the | ||||||
|  |  * argument are board-specific (per include/linux/mtd/nand_new.h): | ||||||
|  |  * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device | ||||||
|  |  * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device | ||||||
|  |  * - hwcontrol: hardwarespecific function for accesing control-lines | ||||||
|  |  * - dev_ready: hardwarespecific function for  accesing device ready/busy line | ||||||
|  |  * - enable_hwecc?: function to enable (reset)  hardware ecc generator. Must | ||||||
|  |  *   only be provided if a hardware ECC is available | ||||||
|  |  * - eccmode: mode of ecc, see defines | ||||||
|  |  * - chip_delay: chip dependent delay for transfering data from array to | ||||||
|  |  *   read regs (tR) | ||||||
|  |  * - options: various chip options. They can partly be set to inform | ||||||
|  |  *   nand_scan about special functionality. See the defines for further | ||||||
|  |  *   explanation | ||||||
|  |  * Members with a "?" were not set in the merged testing-NAND branch, | ||||||
|  |  * so they are not set here either. | ||||||
|  |  */ | ||||||
|  | void board_nand_init(struct nand_chip *nand) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | 	nand->hwcontrol = ppchameleonevb_hwcontrol; | ||||||
|  | 	nand->dev_ready = ppchameleonevb_device_ready; | ||||||
|  | 	nand->eccmode = NAND_ECC_SOFT; | ||||||
|  | 	nand->chip_delay = NAND_BIG_DELAY_US; | ||||||
|  | 	nand->options = NAND_SAMSUNG_LP_OPTIONS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #else | ||||||
|  | 
 | ||||||
|  | /* old NAND handling */ | ||||||
|  | extern ulong | ||||||
|  | nand_probe(ulong physadr); | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | nand_init(void) | ||||||
|  | { | ||||||
|  | 	ulong totlen = 0; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 	The HI model is equipped with a large block NAND chip not supported yet | ||||||
|  | 	by U-Boot | ||||||
|  |     (CONFIG_PPCHAMELEON_MODULE_MODEL == CONFIG_PPCHAMELEON_MODULE_HI) | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #if (CONFIG_PPCHAMELEON_MODULE_MODEL == CONFIG_PPCHAMELEON_MODULE_ME) | ||||||
|  | 	debug ("Probing at 0x%.8x\n", CFG_NAND0_BASE); | ||||||
|  | 	totlen += nand_probe (CFG_NAND0_BASE); | ||||||
|  | #endif	/* CONFIG_PPCHAMELEON_MODULE_ME, CONFIG_PPCHAMELEON_MODULE_HI */ | ||||||
|  | 
 | ||||||
|  | 	debug ("Probing at 0x%.8x\n", CFG_NAND1_BASE); | ||||||
|  | 	totlen += nand_probe (CFG_NAND1_BASE); | ||||||
|  | 
 | ||||||
|  | 	printf ("%3lu MB\n", totlen >>20); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | #endif | ||||||
|  | @ -0,0 +1,85 @@ | ||||||
|  | #
 | ||||||
|  | # (C) Copyright 2005
 | ||||||
|  | # Ladislav Michl, 2N Telekomunikace, michl@2n.cz
 | ||||||
|  | #
 | ||||||
|  | # 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	:= netstar.o flash.o nand.o | ||||||
|  | SOBJS	:= setup.o crcek.o | ||||||
|  | 
 | ||||||
|  | gcclibdir := $(shell dirname `$(CC) -print-libgcc-file-name`) | ||||||
|  | 
 | ||||||
|  | LOAD_ADDR = 0x10400000 | ||||||
|  | LDSCRIPT = $(TOPDIR)/board/$(BOARDDIR)/eeprom.lds | ||||||
|  | 
 | ||||||
|  | HOST_CFLAGS = -Wall -pedantic -I$(TOPDIR)/include | ||||||
|  | 
 | ||||||
|  | all:	$(LIB) eeprom.srec eeprom.bin crcek.srec crcek.bin crcit | ||||||
|  | 
 | ||||||
|  | $(LIB):	$(OBJS) $(SOBJS) | ||||||
|  | 	$(AR) crv $@ $^ | ||||||
|  | 
 | ||||||
|  | eeprom.srec:	eeprom.o eeprom_start.o | ||||||
|  | 	$(LD) -T $(LDSCRIPT) -g -Ttext $(LOAD_ADDR) \
 | ||||||
|  | 		-o $(<:.o=) -e $(<:.o=) $^ \
 | ||||||
|  | 		-L../../examples -lstubs \
 | ||||||
|  | 		-L../../lib_generic -lgeneric \
 | ||||||
|  | 		-L$(gcclibdir) -lgcc | ||||||
|  | 	$(OBJCOPY) -O srec $(<:.o=) $@ | ||||||
|  | 
 | ||||||
|  | eeprom.bin:	eeprom.srec | ||||||
|  | 	$(OBJCOPY) -I srec -O binary $< $@ 2>/dev/null | ||||||
|  | 
 | ||||||
|  | crcek.srec:	crcek.o | ||||||
|  | 	$(LD) -g -Ttext 0x00000000 \
 | ||||||
|  | 		-o $(<:.o=) -e $(<:.o=) $^ | ||||||
|  | 	$(OBJCOPY) -O srec $(<:.o=) $@ | ||||||
|  | 
 | ||||||
|  | crcek.bin:	crcek.srec | ||||||
|  | 	$(OBJCOPY) -I srec -O binary $< $@ 2>/dev/null | ||||||
|  | 
 | ||||||
|  | crcit:		crcit.o crc32.o | ||||||
|  | 	$(HOSTCC) $(HOST_CFLAGS) -o $@ $^ | ||||||
|  | 
 | ||||||
|  | crcit.o:	crcit.c | ||||||
|  | 	$(HOSTCC) $(HOST_CFLAGS) -c $< | ||||||
|  | 
 | ||||||
|  | crc32.o:	$(TOPDIR)/tools/crc32.c | ||||||
|  | 	$(HOSTCC) $(HOST_CFLAGS) -DUSE_HOSTCC -c $< | ||||||
|  | 
 | ||||||
|  | clean: | ||||||
|  | 	rm -f $(SOBJS) $(OBJS) eeprom eeprom.srec eeprom.bin \
 | ||||||
|  | 		crcek crcek.srec crcek.bin | ||||||
|  | 
 | ||||||
|  | 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 | ||||||
|  | 
 | ||||||
|  | #########################################################################
 | ||||||
|  | @ -0,0 +1,15 @@ | ||||||
|  | #
 | ||||||
|  | # Linux-Kernel is expected to be at 1000'8000,
 | ||||||
|  | # entry 1000'8000 (mem base + reserved)
 | ||||||
|  | #
 | ||||||
|  | # We load ourself to internal RAM at 2001'2000
 | ||||||
|  | # Check map file when changing TEXT_BASE.
 | ||||||
|  | # Everything has fit into 192kB internal SRAM!
 | ||||||
|  | #
 | ||||||
|  | 
 | ||||||
|  | # XXX TEXT_BASE = 0x20012000
 | ||||||
|  | TEXT_BASE = 0x13FC0000 | ||||||
|  | 
 | ||||||
|  | # Compile the new NAND code (needed iff #ifdef CONFIG_NEW_NAND_CODE)
 | ||||||
|  | BOARDLIBS = drivers/nand/libnand.a | ||||||
|  | 
 | ||||||
										
											Binary file not shown.
										
									
								
							|  | @ -0,0 +1,177 @@ | ||||||
|  | /** | ||||||
|  |  * (C) Copyright 2005 | ||||||
|  |  * 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
 | ||||||
|  |  * | ||||||
|  |  * This program is free software; you can redistribute it and/or
 | ||||||
|  |  * modify it under the terms of the GNU General Public License | ||||||
|  |  * version 2. | ||||||
|  |  * | ||||||
|  |  * Image layout looks like following: | ||||||
|  |  *	u32 - size | ||||||
|  |  *	u32 - version | ||||||
|  |  *	... - data | ||||||
|  |  *	u32 - crc32 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "crcek.h" | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * do_crc32 - calculate CRC32 of given buffer | ||||||
|  |  * r0 - crc | ||||||
|  |  * r1 - pointer to buffer | ||||||
|  |  * r2 - buffer len | ||||||
|  |  */ | ||||||
|  | 	.macro	do_crc32
 | ||||||
|  | 	ldr	r5, FFFFFFFF | ||||||
|  | 	eor	r0, r0, r5 | ||||||
|  | 	adr	r3, CRC32_TABLE | ||||||
|  | 1: | ||||||
|  | 	ldrb    r4, [r1], #1 | ||||||
|  | 	eor	r4, r4, r0 | ||||||
|  | 	and	r4, r4, #0xff | ||||||
|  | 	ldr	r4, [r3, r4, lsl#2] | ||||||
|  | 	eor	r0, r4, r0, lsr#8 | ||||||
|  | 	subs	r2, r2, #0x1 | ||||||
|  | 	bne 	1b | ||||||
|  | 	eor	r0, r0, r5 | ||||||
|  | 	.endm | ||||||
|  | 
 | ||||||
|  | 	.macro crcuj, offset, size | ||||||
|  | 	mov	r0, #0 | ||||||
|  | 	ldr	r1, \offset | ||||||
|  | 	ldr	r2, [r1] | ||||||
|  | 	cmp	r2, r0		@ no data, no problem
 | ||||||
|  | 	beq	2f | ||||||
|  | 	tst	r2, #3		@ unaligned size
 | ||||||
|  | 	bne	2f | ||||||
|  | 	ldr	r3, \size | ||||||
|  | 	cmp	r2, r3		@ bogus size
 | ||||||
|  | 	bhi	2f | ||||||
|  | 	add	r1, r1, #4 | ||||||
|  | 	do_crc32 | ||||||
|  | 	ldr	r1, [r1] | ||||||
|  | 2: | ||||||
|  | 	cmp	r0, r1 | ||||||
|  | 	.endm | ||||||
|  | 
 | ||||||
|  | 	.macro wait, reg | ||||||
|  | 	mov	\reg, #0x1000 | ||||||
|  | 3: | ||||||
|  | 	subs	\reg, \reg, #0x1 | ||||||
|  | 	bne 	3b | ||||||
|  | 
 | ||||||
|  | 	.endm | ||||||
|  | .text | ||||||
|  | .globl crcek
 | ||||||
|  | crcek: | ||||||
|  | 	b	crc2_bad | ||||||
|  | 	mov	r6, #0 | ||||||
|  | 	crcuj	_LOADER1_OFFSET, _LOADER_SIZE | ||||||
|  | 	bne	crc1_bad | ||||||
|  | 	orr	r6, r6, #1 | ||||||
|  | crc1_bad: | ||||||
|  | 	crcuj	_LOADER2_OFFSET, _LOADER_SIZE | ||||||
|  | 	bne	crc2_bad | ||||||
|  | 	orr	r6, r6, #2 | ||||||
|  | crc2_bad: | ||||||
|  | 	ldr	r3, _LOADER1_OFFSET | ||||||
|  | 	ldr	r4, _LOADER2_OFFSET | ||||||
|  | 	b	boot_2nd | ||||||
|  | 	tst	r6, #3 | ||||||
|  | 	beq	one_is_bad	@ one of them (or both) has bad crc
 | ||||||
|  | 	ldr	r1, [r3, #4] | ||||||
|  | 	ldr	r2, [r4, #4] | ||||||
|  | 	cmp	r1, r2		@ boot 2nd loader if versions differ
 | ||||||
|  | 	beq	boot_1st | ||||||
|  | 	b	boot_2nd | ||||||
|  | one_is_bad: | ||||||
|  | 	tst	r6, #1 | ||||||
|  | 	bne	boot_1st | ||||||
|  | 	tst	r6, #2 | ||||||
|  | 	bne	boot_2nd | ||||||
|  | @ We are doomed, so let user know.
 | ||||||
|  | 	ldr	r0, GPIO_BASE	@ configure GPIO pins
 | ||||||
|  | 	ldr	r1, GPIO_DIRECTION | ||||||
|  | 	strh	r1, [r0, #0x08] | ||||||
|  | blink_loop: | ||||||
|  | 	mov	r1, #0x08 | ||||||
|  | 	strh    r1, [r0, #0x04] | ||||||
|  | 	wait	r3 | ||||||
|  | 	mov	r1, #0x10 | ||||||
|  | 	strh    r1, [r0, #0x04] | ||||||
|  | 	wait	r3 | ||||||
|  | 	b blink_loop | ||||||
|  | boot_1st: | ||||||
|  | 	add	pc, r3, #8 | ||||||
|  | boot_2nd: | ||||||
|  | 	add	pc, r4, #8 | ||||||
|  | 
 | ||||||
|  | _LOADER_SIZE: | ||||||
|  | 	.word LOADER_SIZE - 8	@ minus size and crc32
 | ||||||
|  | _LOADER1_OFFSET: | ||||||
|  | 	.word LOADER1_OFFSET
 | ||||||
|  | _LOADER2_OFFSET: | ||||||
|  | 	.word LOADER2_OFFSET
 | ||||||
|  | 
 | ||||||
|  | FFFFFFFF: | ||||||
|  | 	.word 0xffffffff
 | ||||||
|  | CRC32_TABLE: | ||||||
|  | 	.word 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419 | ||||||
|  | 	.word 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4 | ||||||
|  | 	.word 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07 | ||||||
|  | 	.word 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de | ||||||
|  | 	.word 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856 | ||||||
|  | 	.word 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9 | ||||||
|  | 	.word 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4 | ||||||
|  | 	.word 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b | ||||||
|  | 	.word 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3 | ||||||
|  | 	.word 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a | ||||||
|  | 	.word 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599 | ||||||
|  | 	.word 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924 | ||||||
|  | 	.word 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190 | ||||||
|  | 	.word 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f | ||||||
|  | 	.word 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e | ||||||
|  | 	.word 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01 | ||||||
|  | 	.word 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed | ||||||
|  | 	.word 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950 | ||||||
|  | 	.word 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3 | ||||||
|  | 	.word 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2 | ||||||
|  | 	.word 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a | ||||||
|  | 	.word 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5 | ||||||
|  | 	.word 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010 | ||||||
|  | 	.word 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f | ||||||
|  | 	.word 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17 | ||||||
|  | 	.word 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6 | ||||||
|  | 	.word 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615 | ||||||
|  | 	.word 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8 | ||||||
|  | 	.word 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344 | ||||||
|  | 	.word 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb | ||||||
|  | 	.word 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a | ||||||
|  | 	.word 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5 | ||||||
|  | 	.word 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1 | ||||||
|  | 	.word 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c | ||||||
|  | 	.word 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef | ||||||
|  | 	.word 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236 | ||||||
|  | 	.word 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe | ||||||
|  | 	.word 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31 | ||||||
|  | 	.word 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c | ||||||
|  | 	.word 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713 | ||||||
|  | 	.word 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b | ||||||
|  | 	.word 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242 | ||||||
|  | 	.word 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1 | ||||||
|  | 	.word 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c | ||||||
|  | 	.word 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278 | ||||||
|  | 	.word 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7 | ||||||
|  | 	.word 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66 | ||||||
|  | 	.word 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9 | ||||||
|  | 	.word 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605 | ||||||
|  | 	.word 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8 | ||||||
|  | 	.word 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b | ||||||
|  | 	.word 0x2d02ef8d
 | ||||||
|  | 
 | ||||||
|  | GPIO_BASE: | ||||||
|  | 	.word 0xfffce000
 | ||||||
|  | GPIO_DIRECTION: | ||||||
|  | 	.word 0x0000ffe7
 | ||||||
|  | 
 | ||||||
|  | .end | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | #define LOADER_SIZE	(448 * 1024) | ||||||
|  | #define LOADER1_OFFSET	(128 * 1024) | ||||||
|  | #define LOADER2_OFFSET	(LOADER1_OFFSET + LOADER_SIZE) | ||||||
										
											Binary file not shown.
										
									
								
							|  | @ -0,0 +1,86 @@ | ||||||
|  | /*
 | ||||||
|  |  * (C) Copyright 2005 | ||||||
|  |  * 2N Telekomunikace, Ladislav Michl <michl@2n.cz> | ||||||
|  |  * | ||||||
|  |  * 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 <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <sys/stat.h> | ||||||
|  | #include "crcek.h" | ||||||
|  | 
 | ||||||
|  | extern unsigned long crc32(unsigned long, const unsigned char *, unsigned int); | ||||||
|  | 
 | ||||||
|  | uint32_t data[LOADER_SIZE/4 + 3]; | ||||||
|  | 
 | ||||||
|  | int doit(char *path, unsigned version) | ||||||
|  | { | ||||||
|  | 	uint32_t *p; | ||||||
|  | 	ssize_t size; | ||||||
|  | 	int fd; | ||||||
|  | 
 | ||||||
|  | 	fd = open(path, O_RDONLY); | ||||||
|  | 	if (fd == -1) { | ||||||
|  | 		perror("Error opening file"); | ||||||
|  | 		return EXIT_FAILURE; | ||||||
|  | 	} | ||||||
|  | 	p = data + 2; | ||||||
|  | 	size = read(fd, p, LOADER_SIZE + 4); | ||||||
|  | 	if (size == -1) { | ||||||
|  | 		perror("Error reading file"); | ||||||
|  | 		return EXIT_FAILURE; | ||||||
|  | 	} | ||||||
|  | 	if (size > LOADER_SIZE) { | ||||||
|  | 		fprintf(stderr, "File too large\n"); | ||||||
|  | 		return EXIT_FAILURE; | ||||||
|  | 	} | ||||||
|  | 	size = (((size - 1) >> 2) + 1) << 2; | ||||||
|  | 	data[0] = size + 4;	/* add size of version field */ | ||||||
|  | 	data[1] = version; | ||||||
|  | 	data[(size >> 2) + 2] = crc32(0, (unsigned char *)(data + 1), data[0]); | ||||||
|  | 	close(fd); | ||||||
|  | 
 | ||||||
|  | 	if (write(STDOUT_FILENO, data, size + 3*4) == -1) { | ||||||
|  | 		perror("Error writing file"); | ||||||
|  | 		return EXIT_FAILURE; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return EXIT_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int main(int argc, char **argv) | ||||||
|  | { | ||||||
|  | 	if (argc == 2) { | ||||||
|  | 		return doit(argv[1], 0); | ||||||
|  | 	} else if ((argc == 4) && (strcmp(argv[1], "-v") == 0)) { | ||||||
|  | 		char *endptr, *nptr = argv[2]; | ||||||
|  | 		unsigned ver = strtoul(nptr, &endptr, 0); | ||||||
|  | 		if (nptr != '\0' && endptr == '\0') | ||||||
|  | 			return doit(argv[3], ver); | ||||||
|  | 	} | ||||||
|  | 	fprintf(stderr, "Usage: crcit [-v version] <image>\n"); | ||||||
|  | 
 | ||||||
|  | 	return EXIT_FAILURE; | ||||||
|  | } | ||||||
										
											Binary file not shown.
										
									
								
							|  | @ -0,0 +1,215 @@ | ||||||
|  | /*
 | ||||||
|  |  * (C) Copyright 2005 | ||||||
|  |  * Ladislav Michl, 2N Telekomunikace, michl@2n.cz | ||||||
|  |  * | ||||||
|  |  * 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 version 2 as | ||||||
|  |  * published by the Free Software Foundation. | ||||||
|  |  * | ||||||
|  |  * 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 | ||||||
|  |  * | ||||||
|  |  * Some code shamelessly stolen back from Robin Getz. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define DEBUG | ||||||
|  | 
 | ||||||
|  | #include <common.h> | ||||||
|  | #include <exports.h> | ||||||
|  | #include "../drivers/smc91111.h" | ||||||
|  | 
 | ||||||
|  | #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE | ||||||
|  | 
 | ||||||
|  | static u16 read_eeprom_reg(u16 reg) | ||||||
|  | { | ||||||
|  | 	int timeout; | ||||||
|  | 
 | ||||||
|  | 	SMC_SELECT_BANK(2); | ||||||
|  | 	SMC_outw(reg, PTR_REG); | ||||||
|  | 
 | ||||||
|  | 	SMC_SELECT_BANK(1); | ||||||
|  | 	SMC_outw(SMC_inw (CTL_REG) | CTL_EEPROM_SELECT | CTL_RELOAD, | ||||||
|  | 		 CTL_REG); | ||||||
|  | 	timeout = 100; | ||||||
|  | 	while((SMC_inw (CTL_REG) & CTL_RELOAD) && --timeout) | ||||||
|  | 		udelay(100); | ||||||
|  | 	if (timeout == 0) { | ||||||
|  | 		printf("Timeout Reading EEPROM register %02x\n", reg); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return SMC_inw (GP_REG); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int write_eeprom_reg(u16 value, u16 reg) | ||||||
|  | { | ||||||
|  | 	int timeout; | ||||||
|  | 
 | ||||||
|  | 	SMC_SELECT_BANK(2); | ||||||
|  | 	SMC_outw(reg, PTR_REG); | ||||||
|  | 
 | ||||||
|  | 	SMC_SELECT_BANK(1); | ||||||
|  | 	SMC_outw(value, GP_REG); | ||||||
|  | 	SMC_outw(SMC_inw (CTL_REG) | CTL_EEPROM_SELECT | CTL_STORE, CTL_REG); | ||||||
|  | 	timeout = 100; | ||||||
|  | 	while ((SMC_inw(CTL_REG) & CTL_STORE) && --timeout) | ||||||
|  | 		udelay (100); | ||||||
|  | 	if (timeout == 0) { | ||||||
|  | 		printf("Timeout Writing EEPROM register %02x\n", reg); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int write_data(u16 *buf, int len) | ||||||
|  | { | ||||||
|  | 	u16 reg = 0x23; | ||||||
|  | 
 | ||||||
|  | 	while (len--) | ||||||
|  | 		write_eeprom_reg(*buf++, reg++); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int verify_macaddr(char *s) | ||||||
|  | { | ||||||
|  | 	u16 reg; | ||||||
|  | 	int i, err = 0; | ||||||
|  | 
 | ||||||
|  | 	printf("MAC Address: "); | ||||||
|  | 	err = i = 0; | ||||||
|  | 	for (i = 0; i < 3; i++) { | ||||||
|  | 		reg = read_eeprom_reg(0x20 + i); | ||||||
|  | 		printf("%02x:%02x%c", reg & 0xff, reg >> 8, i != 2 ? ':' : '\n'); | ||||||
|  | 		if (s) | ||||||
|  | 			err |= reg != ((u16 *)s)[i]; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return err ? 0 : 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int set_mac(char *s) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	char *e, eaddr[6]; | ||||||
|  | 
 | ||||||
|  | 	/* turn string into mac value */ | ||||||
|  | 	for (i = 0; i < 6; i++) { | ||||||
|  | 		eaddr[i] = simple_strtoul(s, &e, 16); | ||||||
|  | 		s = (*e) ? e+1 : e; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < 3; i++) | ||||||
|  | 		write_eeprom_reg(*(((u16 *)eaddr) + i), 0x20 + i); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int parse_element(char *s, unsigned char *buf, int len) | ||||||
|  | { | ||||||
|  | 	int cnt; | ||||||
|  | 	char *p, num[3]; | ||||||
|  | 	unsigned char id; | ||||||
|  | 
 | ||||||
|  | 	id = simple_strtoul(s, &p, 16); | ||||||
|  | 	if (*p++ != ':') | ||||||
|  | 		return -1; | ||||||
|  | 	cnt = 2; | ||||||
|  | 	num[2] = 0; | ||||||
|  | 	for (; *p; p += 2) { | ||||||
|  | 		if (p[1] == 0) | ||||||
|  | 			return -2; | ||||||
|  | 		if (cnt + 3 > len) | ||||||
|  | 			return -3; | ||||||
|  | 		num[0] = p[0]; | ||||||
|  | 		num[1] = p[1]; | ||||||
|  | 		buf[cnt++] = simple_strtoul(num, NULL, 16); | ||||||
|  | 	} | ||||||
|  | 	buf[0] = id; | ||||||
|  | 	buf[1] = cnt - 2; | ||||||
|  | 
 | ||||||
|  | 	return cnt; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | extern int crcek(void); | ||||||
|  | 
 | ||||||
|  | int eeprom(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	int i, len, ret; | ||||||
|  | 	unsigned char buf[58], *p; | ||||||
|  | 
 | ||||||
|  | 	app_startup(argv); | ||||||
|  | 	if (get_version() != XF_VERSION) { | ||||||
|  | 		printf("Wrong XF_VERSION.\n"); | ||||||
|  | 		printf("Application expects ABI version %d\n", XF_VERSION); | ||||||
|  | 		printf("Actual U-Boot ABI version %d\n", (int)get_version()); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return crcek(); | ||||||
|  | 
 | ||||||
|  | 	if ((SMC_inw (BANK_SELECT) & 0xFF00) != 0x3300) { | ||||||
|  | 		printf("SMSC91111 not found.\n"); | ||||||
|  | 		return 2; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Called without parameters - print MAC address */ | ||||||
|  | 	if (argc < 2) { | ||||||
|  | 		verify_macaddr(NULL); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Print help message */ | ||||||
|  | 	if (argv[1][1] == 'h') { | ||||||
|  | 		printf("VoiceBlue EEPROM writer\n"); | ||||||
|  | 		printf("Built: %s at %s\n", __DATE__ , __TIME__ ); | ||||||
|  | 		printf("Usage:\n\t<mac_address> [<element_1>] [<...>]\n"); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Try to parse information elements */ | ||||||
|  | 	len = sizeof(buf); | ||||||
|  | 	p = buf; | ||||||
|  | 	for (i = 2; i < argc; i++) { | ||||||
|  | 		ret = parse_element(argv[i], p, len); | ||||||
|  | 		switch (ret) { | ||||||
|  | 		case -1: | ||||||
|  | 			printf("Element %d: malformed\n", i - 1); | ||||||
|  | 			return 3; | ||||||
|  | 		case -2: | ||||||
|  | 			printf("Element %d: odd character count\n", i - 1); | ||||||
|  | 			return 3; | ||||||
|  | 		case -3: | ||||||
|  | 			printf("Out of EEPROM memory\n"); | ||||||
|  | 			return 3; | ||||||
|  | 		default: | ||||||
|  | 			p += ret; | ||||||
|  | 			len -= ret; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* First argument (MAC) is mandatory */ | ||||||
|  | 	set_mac(argv[1]); | ||||||
|  | 	if (verify_macaddr(argv[1])) { | ||||||
|  | 		printf("*** MAC address does not match! ***\n"); | ||||||
|  | 		return 4; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	while (len--) | ||||||
|  | 		*p++ = 0; | ||||||
|  | 
 | ||||||
|  | 	write_data((u16 *)buf, sizeof(buf) >> 1); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,51 @@ | ||||||
|  | /* | ||||||
|  |  * (C) Copyright 2002 | ||||||
|  |  * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> | ||||||
|  |  * (C) Copyright 2005 | ||||||
|  |  * Ladislav Michl, 2N Telekomunikace, <michl@2n.cz> | ||||||
|  |  * | ||||||
|  |  * 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_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") | ||||||
|  | OUTPUT_ARCH(arm) | ||||||
|  | ENTRY(_start) | ||||||
|  | SECTIONS | ||||||
|  | { | ||||||
|  | 	. = ALIGN(4); | ||||||
|  | 	.text      : | ||||||
|  | 	{ | ||||||
|  | 	  eeprom_start.o	(.text) | ||||||
|  | 	  *(.text) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	. = ALIGN(4); | ||||||
|  | 	.rodata : { *(.rodata) } | ||||||
|  | 
 | ||||||
|  | 	. = ALIGN(4); | ||||||
|  | 	.data : { *(.data) } | ||||||
|  | 
 | ||||||
|  | 	. = ALIGN(4); | ||||||
|  | 	.got : { *(.got) } | ||||||
|  | 
 | ||||||
|  | 	. = ALIGN(4); | ||||||
|  | 	__bss_start = .; | ||||||
|  | 	.bss : { *(.bss) } | ||||||
|  | 	_end = .; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,177 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2005  2N Telekomunikace | ||||||
|  |  * | ||||||
|  |  * This program is free software; you can redistribute it and/or
 | ||||||
|  |  * modify it under the terms of the GNU General Public License | ||||||
|  |  * version 2 as published by the Free Software Foundation. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | .globl _start
 | ||||||
|  | _start:	b       eeprom | ||||||
|  | 
 | ||||||
|  | #include "crcek.h" | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * do_crc32 - calculate CRC32 of given buffer | ||||||
|  |  * r0 - crc | ||||||
|  |  * r1 - pointer to buffer | ||||||
|  |  * r2 - buffer len | ||||||
|  |  */ | ||||||
|  | 	.macro	do_crc32
 | ||||||
|  | 	ldr	r5, FFFFFFFF | ||||||
|  | 	eor	r0, r0, r5 | ||||||
|  | 	adr	r3, CRC32_TABLE | ||||||
|  | 1: | ||||||
|  | 	ldrb    r4, [r1], #1 | ||||||
|  | 	eor	r4, r4, r0 | ||||||
|  | 	and	r4, r4, #0xff | ||||||
|  | 	ldr	r4, [r3, r4, lsl#2] | ||||||
|  | 	eor	r0, r4, r0, lsr#8 | ||||||
|  | 	subs	r2, r2, #0x1 | ||||||
|  | 	bne 	1b | ||||||
|  | 	eor	r0, r0, r5 | ||||||
|  | 	.endm | ||||||
|  | 
 | ||||||
|  | 	.macro crcuj, offset, size | ||||||
|  | 	ldr	r1, \offset | ||||||
|  | 	ldr	r2, [r1] | ||||||
|  | 	cmp	r2, #0		@ no data, no problem
 | ||||||
|  | 	beq	2f | ||||||
|  | 	mov     r7, #1 | ||||||
|  | 	tst	r2, #3		@ unaligned size
 | ||||||
|  | 	bne	2f | ||||||
|  | 	mov     r7, #2 | ||||||
|  | 	ldr	r0, \size | ||||||
|  | 	cmp	r2, r0		@ bogus size
 | ||||||
|  | 	bhi	2f | ||||||
|  | 	mov     r7, #3 | ||||||
|  | 	add	r1, r1, #4 | ||||||
|  | 	mov	r0, #0 | ||||||
|  | 	do_crc32 | ||||||
|  | 	ldr	r1, [r1] | ||||||
|  | 2: | ||||||
|  | 	cmp	r0, r1 | ||||||
|  | 	.endm | ||||||
|  | 
 | ||||||
|  | 	.macro wait, reg | ||||||
|  | 	mov	\reg, #0x1000 | ||||||
|  | 3: | ||||||
|  | 	subs	\reg, \reg, #0x1 | ||||||
|  | 	bne 	3b | ||||||
|  | 
 | ||||||
|  | 	.endm | ||||||
|  | .text | ||||||
|  | .globl crcek
 | ||||||
|  | crcek: | ||||||
|  | 	mov	r6, #0 | ||||||
|  | @	crcuj	_LOADER1_OFFSET, _LOADER_SIZE
 | ||||||
|  | @	bne	crc1_bad
 | ||||||
|  | @	orr	r6, r6, #1
 | ||||||
|  | crc1_bad: | ||||||
|  | 	crcuj	_LOADER2_OFFSET, _LOADER_SIZE | ||||||
|  | 	bne	crc2_bad | ||||||
|  | 	orr	r6, r6, #2 | ||||||
|  | crc2_bad: | ||||||
|  | @	mov	r0, r6
 | ||||||
|  | 	mov     pc, lr | ||||||
|  | 	ldr	r3, _LOADER1_OFFSET | ||||||
|  | 	ldr	r4, _LOADER2_OFFSET | ||||||
|  | 	tst	r6, #3 | ||||||
|  | 	beq	one_is_bad	@ one of them (or both) has bad crc
 | ||||||
|  | 	ldr	r1, [r3, #4] | ||||||
|  | 	ldr	r2, [r4, #4] | ||||||
|  | 	cmp	r1, r2		@ boot 2nd loader if versions differ
 | ||||||
|  | 	beq	boot_1st | ||||||
|  | 	b	boot_2nd | ||||||
|  | one_is_bad: | ||||||
|  | 	tst	r6, #1 | ||||||
|  | 	bne	boot_1st | ||||||
|  | 	tst	r6, #2 | ||||||
|  | 	bne	boot_2nd | ||||||
|  | @ We are doomed, so let user know.
 | ||||||
|  | 	ldr	r0, GPIO_BASE	@ configure GPIO pins
 | ||||||
|  | 	ldr	r1, GPIO_DIRECTION | ||||||
|  | 	strh	r1, [r0, #0x08] | ||||||
|  | blink_loop: | ||||||
|  | 	mov	r1, #0x08 | ||||||
|  | 	strh    r1, [r0, #0x04] | ||||||
|  | 	wait	r3 | ||||||
|  | 	mov	r1, #0x10 | ||||||
|  | 	strh    r1, [r0, #0x04] | ||||||
|  | 	wait	r3 | ||||||
|  | 	b blink_loop | ||||||
|  | boot_1st: | ||||||
|  | 	add	pc, r3, #8 | ||||||
|  | boot_2nd: | ||||||
|  | 	add	pc, r4, #8 | ||||||
|  | 
 | ||||||
|  | _LOADER_SIZE: | ||||||
|  | 	.word LOADER_SIZE - 8	@ minus size and crc32
 | ||||||
|  | _LOADER1_OFFSET: | ||||||
|  | 	.word LOADER1_OFFSET
 | ||||||
|  | _LOADER2_OFFSET: | ||||||
|  | 	.word LOADER2_OFFSET
 | ||||||
|  | 
 | ||||||
|  | FFFFFFFF: | ||||||
|  | 	.word 0xffffffff
 | ||||||
|  | CRC32_TABLE: | ||||||
|  | 	.word 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419 | ||||||
|  | 	.word 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4 | ||||||
|  | 	.word 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07 | ||||||
|  | 	.word 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de | ||||||
|  | 	.word 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856 | ||||||
|  | 	.word 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9 | ||||||
|  | 	.word 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4 | ||||||
|  | 	.word 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b | ||||||
|  | 	.word 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3 | ||||||
|  | 	.word 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a | ||||||
|  | 	.word 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599 | ||||||
|  | 	.word 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924 | ||||||
|  | 	.word 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190 | ||||||
|  | 	.word 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f | ||||||
|  | 	.word 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e | ||||||
|  | 	.word 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01 | ||||||
|  | 	.word 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed | ||||||
|  | 	.word 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950 | ||||||
|  | 	.word 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3 | ||||||
|  | 	.word 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2 | ||||||
|  | 	.word 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a | ||||||
|  | 	.word 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5 | ||||||
|  | 	.word 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010 | ||||||
|  | 	.word 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f | ||||||
|  | 	.word 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17 | ||||||
|  | 	.word 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6 | ||||||
|  | 	.word 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615 | ||||||
|  | 	.word 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8 | ||||||
|  | 	.word 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344 | ||||||
|  | 	.word 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb | ||||||
|  | 	.word 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a | ||||||
|  | 	.word 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5 | ||||||
|  | 	.word 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1 | ||||||
|  | 	.word 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c | ||||||
|  | 	.word 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef | ||||||
|  | 	.word 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236 | ||||||
|  | 	.word 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe | ||||||
|  | 	.word 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31 | ||||||
|  | 	.word 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c | ||||||
|  | 	.word 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713 | ||||||
|  | 	.word 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b | ||||||
|  | 	.word 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242 | ||||||
|  | 	.word 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1 | ||||||
|  | 	.word 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c | ||||||
|  | 	.word 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278 | ||||||
|  | 	.word 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7 | ||||||
|  | 	.word 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66 | ||||||
|  | 	.word 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9 | ||||||
|  | 	.word 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605 | ||||||
|  | 	.word 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8 | ||||||
|  | 	.word 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b | ||||||
|  | 	.word 0x2d02ef8d
 | ||||||
|  | 
 | ||||||
|  | GPIO_BASE: | ||||||
|  | 	.word 0xfffce000
 | ||||||
|  | GPIO_DIRECTION: | ||||||
|  | 	.word 0x0000ffe7
 | ||||||
|  | 
 | ||||||
|  | .end | ||||||
|  | @ -0,0 +1,343 @@ | ||||||
|  | /*
 | ||||||
|  |  * (C) Copyright 2002 | ||||||
|  |  * Sysgo Real-Time Solutions, GmbH <www.elinos.com> | ||||||
|  |  * Alex Zuepke <azu@sysgo.de> | ||||||
|  |  * | ||||||
|  |  * (C) Copyright 2005 | ||||||
|  |  * 2N Telekomunikace, a.s. <www.2n.cz> | ||||||
|  |  * Ladislav Michl <michl@2n.cz> | ||||||
|  |  * | ||||||
|  |  * 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 0 */ | ||||||
|  | #if (PHYS_SDRAM_1_SIZE != SZ_32M) | ||||||
|  | 
 | ||||||
|  | #include "crcek.h" | ||||||
|  | 
 | ||||||
|  | #if (CFG_MAX_FLASH_BANKS > 1) | ||||||
|  | #error There is always only _one_ flash chip | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; | ||||||
|  | 
 | ||||||
|  | #define CMD_READ_ARRAY		0x000000f0 | ||||||
|  | #define CMD_UNLOCK1		0x000000aa | ||||||
|  | #define CMD_UNLOCK2		0x00000055 | ||||||
|  | #define CMD_ERASE_SETUP		0x00000080 | ||||||
|  | #define CMD_ERASE_CONFIRM	0x00000030 | ||||||
|  | #define CMD_PROGRAM		0x000000a0 | ||||||
|  | #define CMD_UNLOCK_BYPASS	0x00000020 | ||||||
|  | 
 | ||||||
|  | #define MEM_FLASH_ADDR1		(*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555 << 1))) | ||||||
|  | #define MEM_FLASH_ADDR2		(*(volatile u16 *)(CFG_FLASH_BASE + (0x000002aa << 1))) | ||||||
|  | 
 | ||||||
|  | #define BIT_ERASE_DONE		0x00000080 | ||||||
|  | #define BIT_RDY_MASK		0x00000080 | ||||||
|  | #define BIT_PROGRAM_ERROR	0x00000020 | ||||||
|  | #define BIT_TIMEOUT		0x80000000	/* our flag */ | ||||||
|  | 
 | ||||||
|  | /*-----------------------------------------------------------------------
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | ulong flash_init(void) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	flash_info[0].flash_id = (AMD_MANUFACT & FLASH_VENDMASK) | | ||||||
|  | 				 (AMD_ID_LV800B & FLASH_TYPEMASK); | ||||||
|  | 	flash_info[0].size = PHYS_FLASH_1_SIZE; | ||||||
|  | 	flash_info[0].sector_count = CFG_MAX_FLASH_SECT; | ||||||
|  | 	memset(flash_info[0].protect, 0, CFG_MAX_FLASH_SECT); | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < flash_info[0].sector_count; i++) { | ||||||
|  | 		switch (i) { | ||||||
|  | 		case 0: /* 16kB */ | ||||||
|  | 			flash_info[0].start[0] = CFG_FLASH_BASE; | ||||||
|  | 			break; | ||||||
|  | 		case 1: /* 8kB */ | ||||||
|  | 			flash_info[0].start[1] = CFG_FLASH_BASE + 0x4000; | ||||||
|  | 			break; | ||||||
|  | 		case 2: /* 8kB */ | ||||||
|  | 			flash_info[0].start[2] = CFG_FLASH_BASE + 0x4000 + | ||||||
|  | 						 0x2000; | ||||||
|  | 			break; | ||||||
|  | 		case 3: /* 32 KB */ | ||||||
|  | 			flash_info[0].start[3] = CFG_FLASH_BASE + 0x4000 + | ||||||
|  | 						 2 * 0x2000; | ||||||
|  | 			break; | ||||||
|  | 		case 4: | ||||||
|  | 			flash_info[0].start[4] = CFG_FLASH_BASE + 0x4000 + | ||||||
|  | 						 2 * 0x2000 + 0x8000; | ||||||
|  | 			break; | ||||||
|  | 		default: /* 64kB */ | ||||||
|  | 			flash_info[0].start[i] = flash_info[0].start[i-1] + | ||||||
|  | 						 0x10000; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* U-Boot */ | ||||||
|  | 	flash_protect(FLAG_PROTECT_SET, | ||||||
|  | 		      LOADER1_OFFSET, | ||||||
|  | 		      LOADER1_OFFSET + LOADER_SIZE - 1, flash_info); | ||||||
|  | 	/* Protect crcek, env and r_env as well */ | ||||||
|  | 	flash_protect(FLAG_PROTECT_SET, 0, 0x8000 - 1, flash_info); | ||||||
|  | 
 | ||||||
|  | 	return flash_info[0].size; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*-----------------------------------------------------------------------
 | ||||||
|  |  */ | ||||||
|  | void flash_print_info(flash_info_t *info) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	switch (info->flash_id & FLASH_VENDMASK) { | ||||||
|  | 	case (AMD_MANUFACT & FLASH_VENDMASK): | ||||||
|  | 		puts("AMD: "); | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		puts("Unknown vendor "); | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	switch (info->flash_id & FLASH_TYPEMASK) { | ||||||
|  | 	case (AMD_ID_LV800B & FLASH_TYPEMASK): | ||||||
|  | 		puts("AM29LV800BB (8Mb)\n"); | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		puts("Unknown chip type\n"); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	printf("  Size: %ld MB in %d sectors\n", | ||||||
|  | 	       info->size >> 20, info->sector_count); | ||||||
|  | 
 | ||||||
|  | 	puts("  Sector start addresses:"); | ||||||
|  | 	for (i = 0; i < info->sector_count; i++) { | ||||||
|  | 		if ((i % 5) == 0) | ||||||
|  | 			puts("\n   "); | ||||||
|  | 
 | ||||||
|  | 		printf(" %08lX%s", info->start[i], | ||||||
|  | 		       info->protect[i] ? " (RO)" : "     "); | ||||||
|  | 	} | ||||||
|  | 	puts("\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*-----------------------------------------------------------------------
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | int flash_erase(flash_info_t *info, int s_first, int s_last) | ||||||
|  | { | ||||||
|  | 	ushort result; | ||||||
|  | 	int prot, sect; | ||||||
|  | 	int rc = ERR_OK; | ||||||
|  | 
 | ||||||
|  | 	/* first look for protection bits */ | ||||||
|  | 
 | ||||||
|  | 	if (info->flash_id == FLASH_UNKNOWN) | ||||||
|  | 		return ERR_UNKNOWN_FLASH_TYPE; | ||||||
|  | 
 | ||||||
|  | 	if ((s_first < 0) || (s_first > s_last)) | ||||||
|  | 		return ERR_INVAL; | ||||||
|  | 
 | ||||||
|  | 	if ((info->flash_id & FLASH_VENDMASK) != | ||||||
|  | 	    (AMD_MANUFACT & FLASH_VENDMASK)) | ||||||
|  | 		return ERR_UNKNOWN_FLASH_VENDOR; | ||||||
|  | 
 | ||||||
|  | 	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 | ||||||
|  | 		putc('\n'); | ||||||
|  | 
 | ||||||
|  | 	/* Start erase on unprotected sectors */ | ||||||
|  | 	for (sect = s_first; sect <= s_last && !ctrlc (); sect++) { | ||||||
|  | 		if (info->protect[sect] == 0) {	/* not protected */ | ||||||
|  | 			vu_short *addr = (vu_short *) (info->start[sect]); | ||||||
|  | 
 | ||||||
|  | 			/* arm simple, non interrupt dependent timer */ | ||||||
|  | 			reset_timer_masked(); | ||||||
|  | 
 | ||||||
|  | 			MEM_FLASH_ADDR1 = CMD_UNLOCK1; | ||||||
|  | 			MEM_FLASH_ADDR2 = CMD_UNLOCK2; | ||||||
|  | 			MEM_FLASH_ADDR1 = CMD_ERASE_SETUP; | ||||||
|  | 
 | ||||||
|  | 			MEM_FLASH_ADDR1 = CMD_UNLOCK1; | ||||||
|  | 			MEM_FLASH_ADDR2 = CMD_UNLOCK2; | ||||||
|  | 			*addr = CMD_ERASE_CONFIRM; | ||||||
|  | 
 | ||||||
|  | 			/* wait until flash is ready */ | ||||||
|  | 			while (1) { | ||||||
|  | 				result = *addr; | ||||||
|  | 
 | ||||||
|  | 				/* check timeout */ | ||||||
|  | 				if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) { | ||||||
|  | 					MEM_FLASH_ADDR1 = CMD_READ_ARRAY; | ||||||
|  | 					rc = ERR_TIMOUT; | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				if ((result & 0xfff) & BIT_ERASE_DONE) | ||||||
|  | 					break; | ||||||
|  | 
 | ||||||
|  | 				if ((result & 0xffff) & BIT_PROGRAM_ERROR) { | ||||||
|  | 					rc = ERR_PROG_ERROR; | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			MEM_FLASH_ADDR1 = CMD_READ_ARRAY; | ||||||
|  | 
 | ||||||
|  | 			if (rc != ERR_OK) | ||||||
|  | 				goto out; | ||||||
|  | 
 | ||||||
|  | 			putc('.'); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | out: | ||||||
|  | 	/* allow flash to settle - wait 10 ms */ | ||||||
|  | 	udelay_masked(10000); | ||||||
|  | 
 | ||||||
|  | 	return rc; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*-----------------------------------------------------------------------
 | ||||||
|  |  * Copy memory to flash | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | volatile static int write_hword(flash_info_t *info, ulong dest, ushort data) | ||||||
|  | { | ||||||
|  | 	vu_short *addr = (vu_short *) dest; | ||||||
|  | 	ushort result; | ||||||
|  | 	int rc = ERR_OK; | ||||||
|  | 
 | ||||||
|  | 	/* check if flash is (sufficiently) erased */ | ||||||
|  | 	result = *addr; | ||||||
|  | 	if ((result & data) != data) | ||||||
|  | 		return ERR_NOT_ERASED; | ||||||
|  | 
 | ||||||
|  | 	MEM_FLASH_ADDR1 = CMD_UNLOCK1; | ||||||
|  | 	MEM_FLASH_ADDR2 = CMD_UNLOCK2; | ||||||
|  | 	MEM_FLASH_ADDR1 = CMD_PROGRAM; | ||||||
|  | 	*addr = data; | ||||||
|  | 
 | ||||||
|  | 	/* arm simple, non interrupt dependent timer */ | ||||||
|  | 	reset_timer_masked(); | ||||||
|  | 
 | ||||||
|  | 	/* wait until flash is ready */ | ||||||
|  | 	while (1) { | ||||||
|  | 		result = *addr; | ||||||
|  | 
 | ||||||
|  | 		/* check timeout */ | ||||||
|  | 		if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) { | ||||||
|  | 			rc = ERR_TIMOUT; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if ((result & 0x80) == (data & 0x80)) | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		if ((result & 0xffff) & BIT_PROGRAM_ERROR) { | ||||||
|  | 			result = *addr; | ||||||
|  | 
 | ||||||
|  | 			if ((result & 0x80) != (data & 0x80)) | ||||||
|  | 				rc = ERR_PROG_ERROR; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	*addr = CMD_READ_ARRAY; | ||||||
|  | 
 | ||||||
|  | 	if (*addr != data) | ||||||
|  | 		rc = ERR_PROG_ERROR; | ||||||
|  | 
 | ||||||
|  | 	return rc; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*-----------------------------------------------------------------------
 | ||||||
|  |  * Copy memory to flash. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) | ||||||
|  | { | ||||||
|  | 	ulong cp, wp; | ||||||
|  | 	int l; | ||||||
|  | 	int i, rc; | ||||||
|  | 	ushort data; | ||||||
|  | 
 | ||||||
|  | 	wp = (addr & ~1);	/* 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 << 8); | ||||||
|  | 		for (; i < 2 && cnt > 0; ++i) { | ||||||
|  | 			data = (data >> 8) | (*src++ << 8); | ||||||
|  | 			--cnt; | ||||||
|  | 			++cp; | ||||||
|  | 		} | ||||||
|  | 		for (; cnt == 0 && i < 2; ++i, ++cp) | ||||||
|  | 			data = (data >> 8) | (*(uchar *) cp << 8); | ||||||
|  | 
 | ||||||
|  | 		if ((rc = write_hword(info, wp, data)) != 0) | ||||||
|  | 			return (rc); | ||||||
|  | 		wp += 2; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * handle word aligned part | ||||||
|  | 	 */ | ||||||
|  | 	while (cnt >= 2) { | ||||||
|  | 		data = *((vu_short *) src); | ||||||
|  | 		if ((rc = write_hword(info, wp, data)) != 0) | ||||||
|  | 			return (rc); | ||||||
|  | 		src += 2; | ||||||
|  | 		wp += 2; | ||||||
|  | 		cnt -= 2; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (cnt == 0) | ||||||
|  | 		return ERR_OK; | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * handle unaligned tail bytes | ||||||
|  | 	 */ | ||||||
|  | 	data = 0; | ||||||
|  | 	for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) { | ||||||
|  | 		data = (data >> 8) | (*src++ << 8); | ||||||
|  | 		--cnt; | ||||||
|  | 	} | ||||||
|  | 	for (; i < 2; ++i, ++cp) | ||||||
|  | 		data = (data >> 8) | (*(uchar *) cp << 8); | ||||||
|  | 
 | ||||||
|  | 	return write_hword(info, wp, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -0,0 +1,64 @@ | ||||||
|  | /*
 | ||||||
|  |  * (C) Copyright 2005 2N TELEKOMUNIKACE, Ladislav Michl | ||||||
|  |  * | ||||||
|  |  * 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 (CONFIG_COMMANDS & CFG_CMD_NAND) | ||||||
|  | 
 | ||||||
|  | #include <nand.h> | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  *	hardware specific access to control-lines | ||||||
|  |  */ | ||||||
|  | #define	MASK_CLE	0x02 | ||||||
|  | #define	MASK_ALE	0x04 | ||||||
|  | 
 | ||||||
|  | static void netstar_nand_hwcontrol(struct mtd_info *mtd, int cmd) | ||||||
|  | { | ||||||
|  | 	struct nand_chip *this = mtd->priv; | ||||||
|  | 	ulong IO_ADDR_W = (ulong) this->IO_ADDR_W; | ||||||
|  | 
 | ||||||
|  | 	IO_ADDR_W &= ~(MASK_ALE|MASK_CLE); | ||||||
|  | 	switch (cmd) { | ||||||
|  | 		case NAND_CTL_SETCLE: IO_ADDR_W |= MASK_CLE; break; | ||||||
|  | 		case NAND_CTL_SETALE: IO_ADDR_W |= MASK_ALE; break; | ||||||
|  | 	} | ||||||
|  | 	this->IO_ADDR_W = (void *) IO_ADDR_W; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  *	chip R/B detection | ||||||
|  |  */ | ||||||
|  | static int netstar_nand_ready(struct mtd_info *mtd) | ||||||
|  | { | ||||||
|  | 	return (*(volatile ushort *)GPIO_DATA_INPUT_REG) & 0x02; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void board_nand_init(struct nand_chip *nand) | ||||||
|  | { | ||||||
|  | 	nand->options = NAND_SAMSUNG_LP_OPTIONS; | ||||||
|  | 	nand->eccmode = NAND_ECC_SOFT; | ||||||
|  | 	nand->hwcontrol = netstar_nand_hwcontrol; | ||||||
|  | /*	nand->dev_ready = netstar_nand_ready; */ | ||||||
|  | 	nand->chip_delay = 18; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | @ -0,0 +1,68 @@ | ||||||
|  | /*
 | ||||||
|  |  * (C) Copyright 2005 2N TELEKOMUNIKACE, Ladislav Michl | ||||||
|  |  * | ||||||
|  |  * 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> | ||||||
|  | 
 | ||||||
|  | int board_init(void) | ||||||
|  | { | ||||||
|  | 	DECLARE_GLOBAL_DATA_PTR; | ||||||
|  | 
 | ||||||
|  | 	/* arch number of NetStar board */ | ||||||
|  | 	/* TODO: use define from asm/mach-types.h */ | ||||||
|  | 	gd->bd->bi_arch_number = 692; | ||||||
|  | 
 | ||||||
|  | 	/* adress of boot parameters */ | ||||||
|  | 	gd->bd->bi_boot_params = 0x10000100; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int dram_init(void) | ||||||
|  | { | ||||||
|  | 	DECLARE_GLOBAL_DATA_PTR; | ||||||
|  | 
 | ||||||
|  | 	gd->bd->bi_dram[0].start = PHYS_SDRAM_1; | ||||||
|  | 	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; | ||||||
|  | 
 | ||||||
|  | 	/* Take the Ethernet controller out of reset and wait
 | ||||||
|  | 	 * for the EEPROM load to complete. */ | ||||||
|  | 	*((volatile unsigned short *) GPIO_DATA_OUTPUT_REG) |= 0x80; | ||||||
|  | 	udelay(10);	/* doesn't work before interrupt_init call */ | ||||||
|  | 	*((volatile unsigned short *) GPIO_DATA_OUTPUT_REG) &= ~0x80; | ||||||
|  | 	udelay(500); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | extern void partition_flash(void); | ||||||
|  | 
 | ||||||
|  | int misc_init_r(void) | ||||||
|  | { | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | extern void nand_init(void); | ||||||
|  | 
 | ||||||
|  | int board_late_init(void) | ||||||
|  | { | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,287 @@ | ||||||
|  | /* | ||||||
|  |  * Board specific setup info | ||||||
|  |  * | ||||||
|  |  * (C) Copyright 2004 Ales Jindra <jindra@2n.cz>
 | ||||||
|  |  * (C) Copyright 2005 Ladislav Michl <michl@2n.cz>
 | ||||||
|  |  * | ||||||
|  |  * 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 <config.h> | ||||||
|  | #include <version.h> | ||||||
|  | 
 | ||||||
|  | _TEXT_BASE: | ||||||
|  | 	.word	TEXT_BASE	/* SDRAM load addr from config.mk */ | ||||||
|  | 
 | ||||||
|  | OMAP5910_LPG1_BASE:		.word 0xfffbd000 | ||||||
|  | OMAP5910_TIPB_SWITCHES_BASE:	.word 0xfffbc800 | ||||||
|  | OMAP5910_MPU_TC_BASE:		.word 0xfffecc00 | ||||||
|  | OMAP5910_MPU_CLKM_BASE:		.word 0xfffece00 | ||||||
|  | OMAP5910_ULPD_PWR_MNG_BASE:	.word 0xfffe0800 | ||||||
|  | OMAP5910_DPLL1_BASE:		.word 0xfffecf00 | ||||||
|  | OMAP5910_GPIO_BASE:		.word 0xfffce000 | ||||||
|  | OMAP5910_MPU_WD_TIMER_BASE:	.word 0xfffec800 | ||||||
|  | OMAP5910_MPUI_BASE:		.word 0xfffec900 | ||||||
|  | 
 | ||||||
|  | _OMAP5910_ARM_CKCTL:		.word OMAP5910_ARM_CKCTL | ||||||
|  | _OMAP5910_ARM_EN_CLK:		.word OMAP5910_ARM_EN_CLK | ||||||
|  | 
 | ||||||
|  | OMAP5910_MPUI_CTRL:		.word 0x0000ff1b | ||||||
|  | 
 | ||||||
|  | VAL_EMIFS_CS0_CONFIG:		.word 0x00009090 | ||||||
|  | VAL_EMIFS_CS1_CONFIG:		.word 0x00003031 | ||||||
|  | VAL_EMIFS_CS2_CONFIG:		.word 0x0000a0a1 | ||||||
|  | VAL_EMIFS_CS3_CONFIG:		.word 0x0000c0c0 | ||||||
|  | VAL_EMIFS_DYN_WAIT:		.word 0x00000000 | ||||||
|  | /* autorefresh counter 0x246 ((64000000/13.4)-400)/8192) */ | ||||||
|  | 				/*     SLRF       SD_RET     ARE        SDRAM_TYPE   ARCV           SDRAM_FREQUENCY PWD     CLK */ | ||||||
|  | 
 | ||||||
|  | #if (PHYS_SDRAM_1_SIZE == SZ_32M) | ||||||
|  | VAL_EMIFF_SDRAM_CONFIG:		.word ((0 << 0) | (0 << 1) | (3 << 2) | (0xf << 4) | (0x246 << 8) | (0 << 24) | (0 << 26) | (0 << 27)) | ||||||
|  | #else | ||||||
|  | VAL_EMIFF_SDRAM_CONFIG:		.word ((0 << 0) | (0 << 1) | (3 << 2) | (0xd << 4) | (0x246 << 8) | (0 << 24) | (0 << 26) | (0 << 27)) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | VAL_EMIFF_SDRAM_CONFIG2:	.word 0x00000003 | ||||||
|  | VAL_EMIFF_MRS:			.word 0x00000037 | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * GPIO04 - Green LED (Red LED is connected to LED Pulse Generator) | ||||||
|  |  * GPIO07 - LAN91C111 reset | ||||||
|  |  */ | ||||||
|  | GPIO_DIRECTION: | ||||||
|  | 	.word 0x0000ff6f
 | ||||||
|  | /* | ||||||
|  |  * Disable everything (green LED is connected via invertor) | ||||||
|  |  */ | ||||||
|  | GPIO_OUTPUT: | ||||||
|  | 	.word 0x00000010
 | ||||||
|  | 
 | ||||||
|  | MUX_CONFIG_BASE: | ||||||
|  | 	.word 0xfffe1000
 | ||||||
|  | 
 | ||||||
|  | MUX_CONFIG_VALUES: | ||||||
|  | 	.align 4
 | ||||||
|  | 	.word 0x00000000	@ FUNC_MUX_CTRL_0
 | ||||||
|  | 	.word 0x00000000	@ FUNC_MUX_CTRL_1
 | ||||||
|  | 	.word 0x00000000	@ FUNC_MUX_CTRL_2
 | ||||||
|  | 	.word 0x00000000	@ FUNC_MUX_CTRL_3
 | ||||||
|  | 	.word 0x00000000	@ FUNC_MUX_CTRL_4
 | ||||||
|  | 	.word 0x02080480	@ FUNC_MUX_CTRL_5
 | ||||||
|  | 	.word 0x0100001c	@ FUNC_MUX_CTRL_6
 | ||||||
|  | 	.word 0x0004800b	@ FUNC_MUX_CTRL_7
 | ||||||
|  | 	.word 0x10001200	@ FUNC_MUX_CTRL_8
 | ||||||
|  | 	.word 0x01201012	@ FUNC_MUX_CTRL_9
 | ||||||
|  | 	.word 0x02082248	@ FUNC_MUX_CTRL_A
 | ||||||
|  | 	.word 0x00000248	@ FUNC_MUX_CTRL_B
 | ||||||
|  | 	.word 0x12240000	@ FUNC_MUX_CTRL_C
 | ||||||
|  | 	.word 0x00002000	@ FUNC_MUX_CTRL_D
 | ||||||
|  | 	.word 0x00000000	@ PULL_DWN_CTRL_0
 | ||||||
|  | 	.word 0x00000800	@ PULL_DWN_CTRL_1
 | ||||||
|  | 	.word 0x01801000	@ PULL_DWN_CTRL_2
 | ||||||
|  | 	.word 0x00000000	@ PULL_DWN_CTRL_3
 | ||||||
|  | 	.word 0x00000000	@ GATE_INH_CTRL_0
 | ||||||
|  | 	.word 0x00000000	@ VOLTAGE_CTRL_0
 | ||||||
|  | 	.word 0x00000000	@ TEST_DBG_CTRL_0
 | ||||||
|  | 	.word 0x00000006	@ MOD_CONF_CTRL_0
 | ||||||
|  | 	.word 0x0000eaef	@ COMP_MODE_CTRL_0
 | ||||||
|  | 
 | ||||||
|  | MUX_CONFIG_OFFSETS: | ||||||
|  | 	.align 1
 | ||||||
|  | 	.byte 0x00		@ FUNC_MUX_CTRL_0
 | ||||||
|  | 	.byte 0x04		@ FUNC_MUX_CTRL_1
 | ||||||
|  | 	.byte 0x08		@ FUNC_MUX_CTRL_2
 | ||||||
|  | 	.byte 0x10		@ FUNC_MUX_CTRL_3
 | ||||||
|  | 	.byte 0x14		@ FUNC_MUX_CTRL_4
 | ||||||
|  | 	.byte 0x18		@ FUNC_MUX_CTRL_5
 | ||||||
|  | 	.byte 0x1c		@ FUNC_MUX_CTRL_6
 | ||||||
|  | 	.byte 0x20		@ FUNC_MUX_CTRL_7
 | ||||||
|  | 	.byte 0x24		@ FUNC_MUX_CTRL_8
 | ||||||
|  | 	.byte 0x28		@ FUNC_MUX_CTRL_9
 | ||||||
|  | 	.byte 0x2c		@ FUNC_MUX_CTRL_A
 | ||||||
|  | 	.byte 0x30		@ FUNC_MUX_CTRL_B
 | ||||||
|  | 	.byte 0x34		@ FUNC_MUX_CTRL_C
 | ||||||
|  | 	.byte 0x38		@ FUNC_MUX_CTRL_D
 | ||||||
|  | 	.byte 0x40		@ PULL_DWN_CTRL_0
 | ||||||
|  | 	.byte 0x44		@ PULL_DWN_CTRL_1
 | ||||||
|  | 	.byte 0x48		@ PULL_DWN_CTRL_2
 | ||||||
|  | 	.byte 0x4c		@ PULL_DWN_CTRL_3
 | ||||||
|  | 	.byte 0x50		@ GATE_INH_CTRL_0
 | ||||||
|  | 	.byte 0x60		@ VOLTAGE_CTRL_0
 | ||||||
|  | 	.byte 0x70		@ TEST_DBG_CTRL_0
 | ||||||
|  | 	.byte 0x80		@ MOD_CONF_CTRL_0
 | ||||||
|  | 	.byte 0x0c		@ COMP_MODE_CTRL_0
 | ||||||
|  | 	.byte 0xff
 | ||||||
|  | 
 | ||||||
|  | .globl platformsetup
 | ||||||
|  | platformsetup: | ||||||
|  | 	/* Improve performance a bit... */ | ||||||
|  | 	mrc	p15, 0, r1, c0, c0, 0		@ read C15 ID register
 | ||||||
|  | 	mrc	p15, 0, r1, c0, c0, 1		@ read C15 Cache information register
 | ||||||
|  | 	mrc	p15, 0, r1, c1, c0, 0		@ read C15 Control register
 | ||||||
|  | 	orr	r1, r1, #0x1000			@ enable I-cache, map interrupt vector 0xffff0000
 | ||||||
|  | 	mcr	p15, 0, r1, c1, c0, 0		@ write C15 Control register
 | ||||||
|  | 	mov	r1, #0x00 | ||||||
|  | 	mcr	p15, 0, r1, c7, c5, 0		@ Flush I-cache
 | ||||||
|  | 	nop | ||||||
|  | 	nop | ||||||
|  | 	nop | ||||||
|  | 	nop | ||||||
|  | 
 | ||||||
|  | 	/* Setup clocking mode */ | ||||||
|  | 	ldr	r0, OMAP5910_MPU_CLKM_BASE	@ prepare base of CLOCK unit
 | ||||||
|  | 	ldrh	r1, [r0, #0x18]			@ get reset status
 | ||||||
|  | 	bic	r1, r1, #(7 << 11)		@ clear clock select
 | ||||||
|  | 	orr	r1, r1, #(2 << 11)		@ set synchronous scalable
 | ||||||
|  | 	mov	r2, #0				@ set wait counter to 100 clock cycles
 | ||||||
|  | 
 | ||||||
|  | icache_loop: | ||||||
|  | 	cmp	r2, #0x01 | ||||||
|  | 	streqh	r1, [r0, #0x18] | ||||||
|  | 	add	r2, r2, #0x01 | ||||||
|  | 	cmp	r2, #0x10 | ||||||
|  | 	bne	icache_loop | ||||||
|  | 	nop | ||||||
|  | 
 | ||||||
|  | 	/* Setup clock divisors */ | ||||||
|  | 	ldr	r0, OMAP5910_MPU_CLKM_BASE	@ base of CLOCK unit
 | ||||||
|  | 	ldr	r1, _OMAP5910_ARM_CKCTL | ||||||
|  | 	orr	r1, r1, #0x2000			@ enable DSP clock
 | ||||||
|  | 	strh	r1, [r0, #0x00]			@ setup clock divisors
 | ||||||
|  | 
 | ||||||
|  | 	/* Setup DPLL to generate requested freq */ | ||||||
|  | 	ldr	r0, OMAP5910_DPLL1_BASE		@ base of DPLL1 register
 | ||||||
|  | 	mov	r1, #0x0010			@ set PLL_ENABLE
 | ||||||
|  | 	orr	r1, r1, #0x2000			@ set IOB to new locking
 | ||||||
|  | 	orr	r1, r1, #(OMAP5910_DPLL_MUL << 7) @ setup multiplier CLKREF
 | ||||||
|  | 	orr	r1, r1, #(OMAP5910_DPLL_DIV << 5) @ setup divider CLKREF
 | ||||||
|  | 	strh	r1, [r0]			@ write
 | ||||||
|  | 
 | ||||||
|  | locking: | ||||||
|  | 	ldrh	r1, [r0]			@ get DPLL value
 | ||||||
|  | 	tst	r1, #0x01 | ||||||
|  | 	beq	locking				@ while LOCK not set
 | ||||||
|  | 
 | ||||||
|  | 	/* Enable clock */ | ||||||
|  | 	ldr	r0, OMAP5910_MPU_CLKM_BASE	@ base of CLOCK unit
 | ||||||
|  | 	mov	r1, #(1 << 10)			@ disable idle mode do not check
 | ||||||
|  | 						@ nWAKEUP pin, other remain active
 | ||||||
|  | 	strh	r1, [r0, #0x04] | ||||||
|  | 	ldr	r1, _OMAP5910_ARM_EN_CLK | ||||||
|  | 	strh	r1, [r0, #0x08] | ||||||
|  | 	mov	r1, #0x003f			@ FLASH.RP not enabled in idle and
 | ||||||
|  | 						@ max delayed ( 32 x CLKIN )
 | ||||||
|  | 	strh	r1, [r0, #0x0c] | ||||||
|  | 
 | ||||||
|  | 	/* Configure 5910 pins functions to match our board. */ | ||||||
|  | 	ldr     r0, MUX_CONFIG_BASE | ||||||
|  | 	adr	r1, MUX_CONFIG_VALUES | ||||||
|  | 	adr	r2, MUX_CONFIG_OFFSETS | ||||||
|  | next_mux_cfg: | ||||||
|  | 	ldrb	r3, [r2], #1 | ||||||
|  | 	ldr	r4, [r1], #4 | ||||||
|  | 	cmp	r3, #0xff | ||||||
|  | 	strne	r4, [r0, r3] | ||||||
|  | 	bne	next_mux_cfg | ||||||
|  | 
 | ||||||
|  | 	/* Configure GPIO pins (also disables Green LED) */ | ||||||
|  | 	ldr	r0, OMAP5910_GPIO_BASE | ||||||
|  | 	ldr	r1, GPIO_OUTPUT | ||||||
|  | 	strh    r1, [r0, #0x04] | ||||||
|  | 	ldr	r1, GPIO_DIRECTION | ||||||
|  | 	strh	r1, [r0, #0x08] | ||||||
|  | 
 | ||||||
|  | 	/* EnablePeripherals */ | ||||||
|  | 	ldr	r0, OMAP5910_MPU_CLKM_BASE	@ CLOCK unit
 | ||||||
|  | 	mov	r1, #0x0001			@ Peripheral enable
 | ||||||
|  | 	strh	r1, [r0, #0x14] | ||||||
|  | 
 | ||||||
|  | 	/* Program LED Pulse Generator */ | ||||||
|  | 	ldr	r0, OMAP5910_LPG1_BASE		@ 1st LED Pulse Generator
 | ||||||
|  | 	mov	r1, #0x7F			@ Set obscure frequency in
 | ||||||
|  | 	strb	r1, [r0, #0x00]			@ LCR
 | ||||||
|  | 	mov	r1, #0x01			@ Enable clock (CLK_EN) in
 | ||||||
|  | 	strb    r1, [r0, #0x04]			@ PMR
 | ||||||
|  | 
 | ||||||
|  | 	/* TIPB Lock UART1 */ | ||||||
|  | 	ldr	r0, OMAP5910_TIPB_SWITCHES_BASE	@ prepare base of TIPB switches
 | ||||||
|  | 	mov	r1, #1				@ ARM allocated
 | ||||||
|  | 	strh	r1, [r0,#0x04]			@ clear IRQ line and status bits
 | ||||||
|  | 	strh	r1, [r0,#0x00] | ||||||
|  | 	ldrh	r1, [r0,#0x04] | ||||||
|  | 
 | ||||||
|  | 	/* Disable watchdog */ | ||||||
|  | 	ldr	r0, OMAP5910_MPU_WD_TIMER_BASE | ||||||
|  | 	mov	r1, #0xf5 | ||||||
|  | 	strh	r1, [r0, #0x8] | ||||||
|  | 	mov	r1, #0xa0 | ||||||
|  | 	strh	r1, [r0, #0x8] | ||||||
|  | 
 | ||||||
|  | 	/* Enable MCLK */ | ||||||
|  | 	ldr	r0, OMAP5910_ULPD_PWR_MNG_BASE | ||||||
|  | 	mov	r1, #0x6 | ||||||
|  | 	strh	r1, [r0, #0x34] | ||||||
|  | 	strh	r1, [r0, #0x34] | ||||||
|  | 
 | ||||||
|  | 	/* Setup clock divisors */ | ||||||
|  | 	ldr	r0, OMAP5910_ULPD_PWR_MNG_BASE	@ base of ULDPL DPLL1 register
 | ||||||
|  | 
 | ||||||
|  | 	mov	r1, #0x0010			@ set PLL_ENABLE
 | ||||||
|  | 	orr	r1, r1, #0x2000			@ set IOB to new locking
 | ||||||
|  | 	strh	r1, [r0]			@ write
 | ||||||
|  | 
 | ||||||
|  | ulocking: | ||||||
|  | 	ldrh	r1, [r0]			@ get DPLL value
 | ||||||
|  | 	tst	r1, #1 | ||||||
|  | 	beq	ulocking			@ while LOCK not set
 | ||||||
|  | 
 | ||||||
|  | 	/* EMIF init */ | ||||||
|  | 	ldr	r0, OMAP5910_MPU_TC_BASE | ||||||
|  | 	ldrh	r1, [r0, #0x0c]			@ EMIFS_CONFIG_REG
 | ||||||
|  | 	bic	r1, r1, #0x0c			@ pwr down disabled, flash WP
 | ||||||
|  | 	orr	r1, r1, #0x01 | ||||||
|  | 	str	r1, [r0, #0x0c] | ||||||
|  | 
 | ||||||
|  | 	ldr	r1, VAL_EMIFS_CS0_CONFIG | ||||||
|  | 	str	r1, [r0, #0x10]			@ EMIFS_CS0_CONFIG
 | ||||||
|  | 	ldr	r1, VAL_EMIFS_CS1_CONFIG | ||||||
|  | 	str	r1, [r0, #0x14]			@ EMIFS_CS1_CONFIG
 | ||||||
|  | 	ldr	r1, VAL_EMIFS_CS2_CONFIG | ||||||
|  | 	str	r1, [r0, #0x18]			@ EMIFS_CS2_CONFIG
 | ||||||
|  | 	ldr	r1, VAL_EMIFS_CS3_CONFIG | ||||||
|  | 	str	r1, [r0, #0x1c]			@ EMIFS_CS3_CONFIG
 | ||||||
|  | 	ldr	r1, VAL_EMIFS_DYN_WAIT | ||||||
|  | 	str	r1, [r0, #0x40]			@ EMIFS_CFG_DYN_WAIT
 | ||||||
|  | 
 | ||||||
|  | 	/* Setup SDRAM */ | ||||||
|  | 	ldr	r1, VAL_EMIFF_SDRAM_CONFIG | ||||||
|  | 	str	r1, [r0, #0x20]			@ EMIFF_SDRAM_CONFIG
 | ||||||
|  | 	ldr	r1, VAL_EMIFF_SDRAM_CONFIG2 | ||||||
|  | 	str	r1, [r0, #0x3c]			@ EMIFF_SDRAM_CONFIG2
 | ||||||
|  | 	ldr	r1, VAL_EMIFF_MRS | ||||||
|  | 	str	r1, [r0, #0x24]			@ EMIFF_MRS
 | ||||||
|  | 	/* SDRAM needs 100us to stabilize */ | ||||||
|  | 	mov	r0, #0x4000 | ||||||
|  | sdelay: | ||||||
|  | 	subs	r0, r0, #0x1 | ||||||
|  | 	bne 	sdelay | ||||||
|  | 
 | ||||||
|  | 	/* back to arch calling code */ | ||||||
|  | 	mov	pc, lr | ||||||
|  | .end | ||||||
|  | @ -0,0 +1,55 @@ | ||||||
|  | /* | ||||||
|  |  * (C) Copyright 2002 | ||||||
|  |  * Gary Jennejohn, DENX Software Engineering, <gj@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_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") | ||||||
|  | OUTPUT_ARCH(arm) | ||||||
|  | ENTRY(_start) | ||||||
|  | SECTIONS | ||||||
|  | { | ||||||
|  | 	. = 0x00000000; | ||||||
|  | 
 | ||||||
|  | 	. = ALIGN(4); | ||||||
|  | 	.text      : | ||||||
|  | 	{ | ||||||
|  | 	  cpu/arm925t/start.o	(.text) | ||||||
|  | 	  *(.text) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	. = ALIGN(4); | ||||||
|  | 	.rodata : { *(.rodata) } | ||||||
|  | 
 | ||||||
|  | 	. = ALIGN(4); | ||||||
|  | 	.data : { *(.data) } | ||||||
|  | 
 | ||||||
|  | 	. = ALIGN(4); | ||||||
|  | 	.got : { *(.got) } | ||||||
|  | 
 | ||||||
|  | 	__u_boot_cmd_start = .; | ||||||
|  | 	.u_boot_cmd : { *(.u_boot_cmd) } | ||||||
|  | 	__u_boot_cmd_end = .; | ||||||
|  | 
 | ||||||
|  | 	. = ALIGN(4); | ||||||
|  | 	__bss_start = .; | ||||||
|  | 	.bss : { *(.bss) } | ||||||
|  | 	_end = .; | ||||||
|  | } | ||||||
|  | @ -37,7 +37,7 @@ COBJS	= main.o ACEX1K.o altera.o bedbug.o circbuf.o \ | ||||||
| 	  cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \
 | 	  cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \
 | ||||||
| 	  cmd_load.o cmd_log.o \
 | 	  cmd_load.o cmd_log.o \
 | ||||||
| 	  cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \
 | 	  cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \
 | ||||||
| 	  cmd_nand.o cmd_net.o cmd_nvedit.o \
 | 	  cmd_nand.o cmd_nand_new.o cmd_net.o cmd_nvedit.o \
 | ||||||
| 	  cmd_pci.o cmd_pcmcia.o cmd_portio.o \
 | 	  cmd_pci.o cmd_pcmcia.o cmd_portio.o \
 | ||||||
| 	  cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o \
 | 	  cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o \
 | ||||||
| 	  cmd_usb.o cmd_vfd.o \
 | 	  cmd_usb.o cmd_vfd.o \
 | ||||||
|  |  | ||||||
|  | @ -99,11 +99,15 @@ | ||||||
| 
 | 
 | ||||||
| #include <cramfs/cramfs_fs.h> | #include <cramfs/cramfs_fs.h> | ||||||
| 
 | 
 | ||||||
| /* enable/disable debugging messages */ | #ifdef CONFIG_NEW_NAND_CODE | ||||||
| #define	DEBUG | #include <nand.h> | ||||||
| #undef	DEBUG | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef  DEBUG | /* enable/disable debugging messages */ | ||||||
|  | #define	DEBUG_JFFS | ||||||
|  | #undef	DEBUG_JFFS | ||||||
|  | 
 | ||||||
|  | #ifdef  DEBUG_JFFS | ||||||
| # define DEBUGF(fmt, args...)	printf(fmt ,##args) | # define DEBUGF(fmt, args...)	printf(fmt ,##args) | ||||||
| #else | #else | ||||||
| # define DEBUGF(fmt, args...) | # define DEBUGF(fmt, args...) | ||||||
|  | @ -123,7 +127,7 @@ | ||||||
| 
 | 
 | ||||||
| /* this flag needs to be set in part_info struct mask_flags
 | /* this flag needs to be set in part_info struct mask_flags
 | ||||||
|  * field for read-only partitions */ |  * field for read-only partitions */ | ||||||
| #define MTD_WRITEABLE		1 | #define MTD_WRITEABLE_CMD		1 | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_JFFS2_CMDLINE | #ifdef CONFIG_JFFS2_CMDLINE | ||||||
| /* default values for mtdids and mtdparts variables */ | /* default values for mtdids and mtdparts variables */ | ||||||
|  | @ -365,10 +369,9 @@ static int part_validate_nand(struct mtdids *id, struct part_info *part) | ||||||
| { | { | ||||||
| #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) | #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) | ||||||
| 	/* info for NAND chips */ | 	/* info for NAND chips */ | ||||||
| 	extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; | 	nand_info_t *nand; | ||||||
| 	struct nand_chip *nand; |  | ||||||
| 
 | 
 | ||||||
| 	nand = &nand_dev_desc[id->num]; | 	nand = &nand_info[id->num]; | ||||||
| 
 | 
 | ||||||
| 	if ((unsigned long)(part->offset) % nand->erasesize) { | 	if ((unsigned long)(part->offset) % nand->erasesize) { | ||||||
| 		printf("%s%d: partition (%s) start offset alignment incorrect\n", | 		printf("%s%d: partition (%s) start offset alignment incorrect\n", | ||||||
|  | @ -464,7 +467,9 @@ static int part_del(struct mtd_device *dev, struct part_info *part) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | #ifndef CONFIG_NEW_NAND_CODE | ||||||
| 	jffs2_free_cache(part); | 	jffs2_free_cache(part); | ||||||
|  | #endif | ||||||
| 	list_del(&part->link); | 	list_del(&part->link); | ||||||
| 	free(part); | 	free(part); | ||||||
| 	dev->num_parts--; | 	dev->num_parts--; | ||||||
|  | @ -491,7 +496,9 @@ static void part_delall(struct list_head *head) | ||||||
| 	list_for_each_safe(entry, n, head) { | 	list_for_each_safe(entry, n, head) { | ||||||
| 		part_tmp = list_entry(entry, struct part_info, link); | 		part_tmp = list_entry(entry, struct part_info, link); | ||||||
| 
 | 
 | ||||||
|  | #ifndef CONFIG_NEW_NAND_CODE | ||||||
| 		jffs2_free_cache(part_tmp); | 		jffs2_free_cache(part_tmp); | ||||||
|  | #endif | ||||||
| 		list_del(entry); | 		list_del(entry); | ||||||
| 		free(part_tmp); | 		free(part_tmp); | ||||||
| 	} | 	} | ||||||
|  | @ -646,7 +653,7 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i | ||||||
| 	/* test for options */ | 	/* test for options */ | ||||||
| 	mask_flags = 0; | 	mask_flags = 0; | ||||||
| 	if (strncmp(p, "ro", 2) == 0) { | 	if (strncmp(p, "ro", 2) == 0) { | ||||||
| 		mask_flags |= MTD_WRITEABLE; | 		mask_flags |= MTD_WRITEABLE_CMD; | ||||||
| 		p += 2; | 		p += 2; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -713,6 +720,7 @@ static int device_validate(u8 type, u8 num, u32 *size) | ||||||
| 		if (num < CFG_MAX_FLASH_BANKS) { | 		if (num < CFG_MAX_FLASH_BANKS) { | ||||||
| 			extern flash_info_t flash_info[]; | 			extern flash_info_t flash_info[]; | ||||||
| 			*size = flash_info[num].size; | 			*size = flash_info[num].size; | ||||||
|  | 
 | ||||||
| 			return 0; | 			return 0; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -724,8 +732,12 @@ static int device_validate(u8 type, u8 num, u32 *size) | ||||||
| 	} else if (type == MTD_DEV_TYPE_NAND) { | 	} else if (type == MTD_DEV_TYPE_NAND) { | ||||||
| #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) | #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) | ||||||
| 		if (num < CFG_MAX_NAND_DEVICE) { | 		if (num < CFG_MAX_NAND_DEVICE) { | ||||||
|  | #ifdef CONFIG_NEW_NAND_CODE | ||||||
|  | 			*size = nand_info[num].size; | ||||||
|  | #else | ||||||
| 			extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; | 			extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; | ||||||
| 			*size = nand_dev_desc[num].totlen; | 			*size = nand_dev_desc[num].totlen; | ||||||
|  | #endif | ||||||
| 			return 0; | 			return 0; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -1169,7 +1181,7 @@ static int generate_mtdparts(char *buf, u32 buflen) | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			/* ro mask flag */ | 			/* ro mask flag */ | ||||||
| 			if (part->mask_flags && MTD_WRITEABLE) { | 			if (part->mask_flags && MTD_WRITEABLE_CMD) { | ||||||
| 				len = 2; | 				len = 2; | ||||||
| 				if (len > maxlen) | 				if (len > maxlen) | ||||||
| 					goto cleanup; | 					goto cleanup; | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ | ||||||
| # define SHOW_BOOT_PROGRESS(arg) | # define SHOW_BOOT_PROGRESS(arg) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #if (CONFIG_COMMANDS & CFG_CMD_NAND) | #if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) | ||||||
| 
 | 
 | ||||||
| #include <linux/mtd/nand.h> | #include <linux/mtd/nand.h> | ||||||
| #include <linux/mtd/nand_ids.h> | #include <linux/mtd/nand_ids.h> | ||||||
|  |  | ||||||
|  | @ -0,0 +1,364 @@ | ||||||
|  | #include <common.h> | ||||||
|  | 
 | ||||||
|  | #if (CONFIG_COMMANDS & CFG_CMD_NAND) && defined CONFIG_NEW_NAND_CODE | ||||||
|  | 
 | ||||||
|  | #include <command.h> | ||||||
|  | #include <watchdog.h> | ||||||
|  | #include <malloc.h> | ||||||
|  | #include <asm/byteorder.h> | ||||||
|  | 
 | ||||||
|  | #ifdef CONFIG_SHOW_BOOT_PROGRESS | ||||||
|  | # include <status_led.h> | ||||||
|  | # define SHOW_BOOT_PROGRESS(arg)	show_boot_progress(arg) | ||||||
|  | #else | ||||||
|  | # define SHOW_BOOT_PROGRESS(arg) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include <jffs2/jffs2.h> | ||||||
|  | #include <nand.h> | ||||||
|  | 
 | ||||||
|  | extern nand_info_t nand_info[];       /* info for NAND chips */ | ||||||
|  | 
 | ||||||
|  | static int nand_dump_oob(nand_info_t *nand, ulong off) | ||||||
|  | { | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int nand_dump(nand_info_t *nand, ulong off) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	u_char *buf, *p; | ||||||
|  | 
 | ||||||
|  | 	buf = malloc(nand->oobblock + nand->oobsize); | ||||||
|  | 	if (!buf) { | ||||||
|  | 		puts("No memory for page buffer\n"); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 	off &= ~(nand->oobblock - 1); | ||||||
|  | 	i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize); | ||||||
|  | 	if (i < 0) { | ||||||
|  | 		printf("Error (%d) reading page %08x\n", i, off); | ||||||
|  | 		free(buf); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 	printf("Page %08x dump:\n", off); | ||||||
|  | 	i = nand->oobblock >> 4; p = buf; | ||||||
|  | 	while (i--) { | ||||||
|  | 		printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x" | ||||||
|  | 			"  %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||||||
|  | 			p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], | ||||||
|  | 			p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); | ||||||
|  | 		p += 16; | ||||||
|  | 	} | ||||||
|  | 	puts("OOB:\n"); | ||||||
|  | 	i = nand->oobsize >> 3; | ||||||
|  | 	while (i--) { | ||||||
|  | 		printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n", | ||||||
|  | 			p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); | ||||||
|  | 		p += 8; | ||||||
|  | 	} | ||||||
|  | 	free(buf); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* ------------------------------------------------------------------------- */ | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | arg_off_size(int argc, char *argv[], ulong *off, ulong *size, ulong totsize) | ||||||
|  | { | ||||||
|  | 	*off = 0; | ||||||
|  | 	*size = 0; | ||||||
|  | 
 | ||||||
|  | #if defined(CONFIG_JFFS2_NAND) && defined(CFG_JFFS_CUSTOM_PART) | ||||||
|  | 	if (argc >= 1 && strcmp(argv[0], "partition") == 0) { | ||||||
|  | 		int part_num; | ||||||
|  | 		struct part_info *part; | ||||||
|  | 		const char *partstr; | ||||||
|  | 
 | ||||||
|  | 		if (argc >= 2) | ||||||
|  | 			partstr = argv[1]; | ||||||
|  | 		else | ||||||
|  | 			partstr = getenv("partition"); | ||||||
|  | 
 | ||||||
|  | 		if (partstr) | ||||||
|  | 			part_num = (int)simple_strtoul(partstr, NULL, 10); | ||||||
|  | 		else | ||||||
|  | 			part_num = 0; | ||||||
|  | 
 | ||||||
|  | 		part = jffs2_part_info(part_num); | ||||||
|  | 		if (part == NULL) { | ||||||
|  | 			printf("\nInvalid partition %d\n", part_num); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 		*size = part->size; | ||||||
|  | 		*off = (ulong)part->offset; | ||||||
|  | 	} else | ||||||
|  | #endif | ||||||
|  | 	{ | ||||||
|  | 		if (argc >= 1) | ||||||
|  | 			*off = (ulong)simple_strtoul(argv[0], NULL, 16); | ||||||
|  | 		else | ||||||
|  | 			*off = 0; | ||||||
|  | 
 | ||||||
|  | 		if (argc >= 2) | ||||||
|  | 			*size = (ulong)simple_strtoul(argv[1], NULL, 16); | ||||||
|  | 		else | ||||||
|  | 			*size = totsize - *off; | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	int i, dev, ret; | ||||||
|  | 	ulong addr, off, size; | ||||||
|  | 	char *cmd, *s; | ||||||
|  | 	nand_info_t *nand; | ||||||
|  | 
 | ||||||
|  | 	/* at least two arguments please */ | ||||||
|  | 	if (argc < 2) | ||||||
|  | 		goto usage; | ||||||
|  | 
 | ||||||
|  | 	cmd = argv[1]; | ||||||
|  | 
 | ||||||
|  | 	if (strcmp(cmd, "info") == 0) { | ||||||
|  | 
 | ||||||
|  | 		putc('\n'); | ||||||
|  | 		for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) { | ||||||
|  | 			if (nand_info[i].name) | ||||||
|  | 				printf("Device %d: %s\n", i, nand_info[i].name); | ||||||
|  | 		} | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (strcmp(cmd, "device") == 0) { | ||||||
|  | 
 | ||||||
|  | 		if (argc < 3) { | ||||||
|  | 			if ((nand_curr_device < 0) || | ||||||
|  | 			    (nand_curr_device >= CFG_MAX_NAND_DEVICE)) | ||||||
|  | 				puts("\nno devices available\n"); | ||||||
|  | 			else | ||||||
|  | 				printf("\nDevice %d: %s\n", nand_curr_device, | ||||||
|  | 					nand_info[nand_curr_device].name); | ||||||
|  | 			return 0; | ||||||
|  | 		} | ||||||
|  | 		dev = (int)simple_strtoul(argv[2], NULL, 10); | ||||||
|  | 		if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { | ||||||
|  | 			puts("No such device\n"); | ||||||
|  | 			return 1; | ||||||
|  | 		} | ||||||
|  | 		printf("Device %d: %s", dev, nand_info[dev].name); | ||||||
|  | 		puts("... is now current device\n"); | ||||||
|  | 		nand_curr_device = dev; | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 && | ||||||
|  | 	    strncmp(cmd, "dump", 4) != 0 && | ||||||
|  | 	    strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0) | ||||||
|  | 		goto usage; | ||||||
|  | 
 | ||||||
|  | 	/* the following commands operate on the current device */ | ||||||
|  | 	if (nand_curr_device < 0 || nand_curr_device >= CFG_MAX_NAND_DEVICE || | ||||||
|  | 	    !nand_info[nand_curr_device].name) { | ||||||
|  | 		puts("\nno devices available\n"); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 	nand = &nand_info[nand_curr_device]; | ||||||
|  | 
 | ||||||
|  | 	if (strcmp(cmd, "bad") == 0) { | ||||||
|  | 		printf("\nDevice %d bad blocks:\n", nand_curr_device); | ||||||
|  | 		for (off = 0; off < nand->size; off += nand->erasesize) | ||||||
|  | 			if (nand_block_isbad(nand, off)) | ||||||
|  | 				printf("  %08x\n", off); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (strcmp(cmd, "erase") == 0) { | ||||||
|  | 		arg_off_size(argc - 2, argv + 2, &off, &size, nand->size); | ||||||
|  | 		if (off == 0 && size == 0) | ||||||
|  | 			return 1; | ||||||
|  | 
 | ||||||
|  | 		printf("\nNAND erase: device %d offset 0x%x, size 0x%x ", | ||||||
|  | 		       nand_curr_device, off, size); | ||||||
|  | 		ret = nand_erase(nand, off, size); | ||||||
|  | 		printf("%s\n", ret ? "ERROR" : "OK"); | ||||||
|  | 
 | ||||||
|  | 		return ret == 0 ? 0 : 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (strncmp(cmd, "dump", 4) == 0) { | ||||||
|  | 		if (argc < 3) | ||||||
|  | 			goto usage; | ||||||
|  | 
 | ||||||
|  | 		s = strchr(cmd, '.'); | ||||||
|  | 		off = (int)simple_strtoul(argv[2], NULL, 16); | ||||||
|  | 
 | ||||||
|  | 		if (s != NULL && strcmp(s, ".oob") == 0) | ||||||
|  | 			ret = nand_dump_oob(nand, off); | ||||||
|  | 		else | ||||||
|  | 			ret = nand_dump(nand, off); | ||||||
|  | 
 | ||||||
|  | 		return ret == 0 ? 1 : 0; | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* read write */ | ||||||
|  | 	if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { | ||||||
|  | 		if (argc < 4) | ||||||
|  | 			goto usage; | ||||||
|  | /*
 | ||||||
|  | 		s = strchr(cmd, '.'); | ||||||
|  | 		clean = CLEAN_NONE; | ||||||
|  | 		if (s != NULL) { | ||||||
|  | 			if (strcmp(s, ".jffs2") == 0 || strcmp(s, ".e") == 0 | ||||||
|  | 			    || strcmp(s, ".i")) | ||||||
|  | 				clean = CLEAN_JFFS2; | ||||||
|  | 		} | ||||||
|  | */ | ||||||
|  | 		addr = (ulong)simple_strtoul(argv[2], NULL, 16); | ||||||
|  | 
 | ||||||
|  | 		arg_off_size(argc - 3, argv + 3, &off, &size, nand->size); | ||||||
|  | 		if (off == 0 && size == 0) | ||||||
|  | 			return 1; | ||||||
|  | 
 | ||||||
|  | 		i = strncmp(cmd, "read", 4) == 0;	/* 1 = read, 0 = write */ | ||||||
|  | 		printf("\nNAND %s: device %d offset %u, size %u ... ", | ||||||
|  | 		       i ? "read" : "write", nand_curr_device, off, size); | ||||||
|  | 
 | ||||||
|  | 		if (i) | ||||||
|  | 			ret = nand_read(nand, off, &size, (u_char *)addr); | ||||||
|  | 		else | ||||||
|  | 			ret = nand_write(nand, off, &size, (u_char *)addr); | ||||||
|  | 
 | ||||||
|  | 		printf(" %d bytes %s: %s\n", size, | ||||||
|  | 		       i ? "read" : "written", ret ? "ERROR" : "OK"); | ||||||
|  | 
 | ||||||
|  | 		return ret == 0 ? 0 : 1; | ||||||
|  | 	} | ||||||
|  | usage: | ||||||
|  | 	printf("Usage:\n%s\n", cmdtp->usage); | ||||||
|  | 	return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | U_BOOT_CMD(nand, 5, 1, do_nand, | ||||||
|  | 	"nand    - NAND sub-system\n", | ||||||
|  | 	"info                  - show available NAND devices\n" | ||||||
|  | 	"nand device [dev]     - show or set current device\n" | ||||||
|  | 	"nand read[.jffs2]     - addr off size\n" | ||||||
|  | 	"nand write[.jffs2]    - addr off size - read/write `size' bytes starting\n" | ||||||
|  | 	"    at offset `off' to/from memory address `addr'\n" | ||||||
|  | 	"nand erase [clean] [off size] - erase `size' bytes from\n" | ||||||
|  | 	"    offset `off' (entire device if not specified)\n" | ||||||
|  | 	"nand bad - show bad blocks\n" | ||||||
|  | 	"nand dump[.oob] off - dump page\n" | ||||||
|  | 	"nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n" | ||||||
|  | 	"nand markbad off - mark bad block at offset (UNSAFE)\n" | ||||||
|  | 	"nand biterr off - make a bit error at offset (UNSAFE)\n"); | ||||||
|  | 
 | ||||||
|  | int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	char *boot_device = NULL; | ||||||
|  | 	char *ep; | ||||||
|  | 	int dev; | ||||||
|  | 	int r; | ||||||
|  | 	ulong addr, cnt, offset = 0; | ||||||
|  | 	image_header_t *hdr; | ||||||
|  | 	nand_info_t *nand; | ||||||
|  | 
 | ||||||
|  | 	switch (argc) { | ||||||
|  | 	case 1: | ||||||
|  | 		addr = CFG_LOAD_ADDR; | ||||||
|  | 		boot_device = getenv("bootdevice"); | ||||||
|  | 		break; | ||||||
|  | 	case 2: | ||||||
|  | 		addr = simple_strtoul(argv[1], NULL, 16); | ||||||
|  | 		boot_device = getenv("bootdevice"); | ||||||
|  | 		break; | ||||||
|  | 	case 3: | ||||||
|  | 		addr = simple_strtoul(argv[1], NULL, 16); | ||||||
|  | 		boot_device = argv[2]; | ||||||
|  | 		break; | ||||||
|  | 	case 4: | ||||||
|  | 		addr = simple_strtoul(argv[1], NULL, 16); | ||||||
|  | 		boot_device = argv[2]; | ||||||
|  | 		offset = simple_strtoul(argv[3], NULL, 16); | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		printf("Usage:\n%s\n", cmdtp->usage); | ||||||
|  | 		SHOW_BOOT_PROGRESS(-1); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (!boot_device) { | ||||||
|  | 		puts("\n** No boot device **\n"); | ||||||
|  | 		SHOW_BOOT_PROGRESS(-1); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	dev = simple_strtoul(boot_device, &ep, 16); | ||||||
|  | 
 | ||||||
|  | 	if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) { | ||||||
|  | 		printf("\n** Device %d not available\n", dev); | ||||||
|  | 		SHOW_BOOT_PROGRESS(-1); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	nand = &nand_info[dev]; | ||||||
|  | 	printf("\nLoading from device %d: %s (offset 0x%lx)\n", | ||||||
|  | 	       dev, nand->name, offset); | ||||||
|  | 
 | ||||||
|  | 	cnt = nand->oobblock; | ||||||
|  | 	r = nand_read(nand, offset, &cnt, (u_char *) addr); | ||||||
|  | 	if (r) { | ||||||
|  | 		printf("** Read error on %d\n", dev); | ||||||
|  | 		SHOW_BOOT_PROGRESS(-1); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	hdr = (image_header_t *) addr; | ||||||
|  | 
 | ||||||
|  | 	if (ntohl(hdr->ih_magic) != IH_MAGIC) { | ||||||
|  | 		printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic); | ||||||
|  | 		SHOW_BOOT_PROGRESS(-1); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	print_image_hdr(hdr); | ||||||
|  | 
 | ||||||
|  | 	cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t)); | ||||||
|  | 
 | ||||||
|  | 	r = nand_read(nand, offset, &cnt, (u_char *) addr); | ||||||
|  | 	if (r) { | ||||||
|  | 		printf("** Read error on %d\n", dev); | ||||||
|  | 		SHOW_BOOT_PROGRESS(-1); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Loading ok, update default load address */ | ||||||
|  | 
 | ||||||
|  | 	load_addr = addr; | ||||||
|  | 
 | ||||||
|  | 	/* Check if we should attempt an auto-start */ | ||||||
|  | 	if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) { | ||||||
|  | 		char *local_args[2]; | ||||||
|  | 		extern int do_bootm(cmd_tbl_t *, int, int, char *[]); | ||||||
|  | 
 | ||||||
|  | 		local_args[0] = argv[0]; | ||||||
|  | 		local_args[1] = NULL; | ||||||
|  | 
 | ||||||
|  | 		printf("Automatic boot of image at addr 0x%08lx ...\n", addr); | ||||||
|  | 
 | ||||||
|  | 		do_bootm(cmdtp, 0, 1, local_args); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | U_BOOT_CMD(nboot, 4, 1, do_nandboot, | ||||||
|  | 	"nboot   - boot from NAND device\n", "loadAddr dev\n"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif				/* (CONFIG_COMMANDS & CFG_CMD_NAND) */ | ||||||
|  | @ -0,0 +1,16 @@ | ||||||
|  | include $(TOPDIR)/config.mk | ||||||
|  | 
 | ||||||
|  | LIB := libnand.a | ||||||
|  | 
 | ||||||
|  | OBJS := nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o | ||||||
|  | all:	$(LIB) | ||||||
|  | 
 | ||||||
|  | $(LIB):	$(OBJS) | ||||||
|  | 	$(AR) crv $@ $(OBJS) | ||||||
|  | 
 | ||||||
|  | #########################################################################
 | ||||||
|  | 
 | ||||||
|  | .depend:	Makefile $(OBJS:.o=.c) | ||||||
|  | 		$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@ | ||||||
|  | 
 | ||||||
|  | sinclude .depend | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -0,0 +1,76 @@ | ||||||
|  | /*
 | ||||||
|  |  * (C) Copyright 2005 | ||||||
|  |  * 2N Telekomunikace, a.s. <www.2n.cz> | ||||||
|  |  * Ladislav Michl <michl@2n.cz> | ||||||
|  |  * | ||||||
|  |  * 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 | ||||||
|  |  * version 2 as published by the Free Software Foundation. | ||||||
|  |  * | ||||||
|  |  * 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> | ||||||
|  | 
 | ||||||
|  | #ifdef CONFIG_NEW_NAND_CODE | ||||||
|  | #if (CONFIG_COMMANDS & CFG_CMD_NAND) | ||||||
|  | 
 | ||||||
|  | #include <nand.h> | ||||||
|  | 
 | ||||||
|  | #ifndef CFG_NAND_BASE_LIST | ||||||
|  | #define CFG_NAND_BASE_LIST { CFG_NAND_BASE } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | int nand_curr_device = -1; | ||||||
|  | nand_info_t nand_info[CFG_MAX_NAND_DEVICE]; | ||||||
|  | 
 | ||||||
|  | static struct nand_chip nand_chip[CFG_MAX_NAND_DEVICE]; | ||||||
|  | static ulong base_address[CFG_MAX_NAND_DEVICE] = CFG_NAND_BASE_LIST; | ||||||
|  | 
 | ||||||
|  | static const char default_nand_name[] = "nand"; | ||||||
|  | 
 | ||||||
|  | extern void board_nand_init(struct nand_chip *nand); | ||||||
|  | 
 | ||||||
|  | static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand, | ||||||
|  | 			   ulong base_addr) | ||||||
|  | { | ||||||
|  | 	mtd->priv = nand; | ||||||
|  | 
 | ||||||
|  | 	nand->IO_ADDR_R = nand->IO_ADDR_W = (void  __iomem *)base_addr; | ||||||
|  | 	board_nand_init(nand); | ||||||
|  | 
 | ||||||
|  | 	if (nand_scan(mtd, 1) == 0) { | ||||||
|  | 		if (!mtd->name) | ||||||
|  | 			mtd->name = (char *)default_nand_name; | ||||||
|  | 	} else | ||||||
|  | 		mtd->name = NULL; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nand_init(void) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	unsigned int size = 0; | ||||||
|  | 	for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) { | ||||||
|  | 		nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]); | ||||||
|  | 		size += nand_info[i].size; | ||||||
|  | 		if (nand_curr_device == -1) | ||||||
|  | 			nand_curr_device = i; | ||||||
|  | } | ||||||
|  | 	printf("%lu MiB\n", size / (1024 * 1024)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | #endif /* CONFIG_NEW_NAND_CODE */ | ||||||
|  | 
 | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -0,0 +1,247 @@ | ||||||
|  | /*
 | ||||||
|  |  * This file contains an ECC algorithm from Toshiba that detects and | ||||||
|  |  * corrects 1 bit errors in a 256 byte block of data. | ||||||
|  |  * | ||||||
|  |  * drivers/mtd/nand/nand_ecc.c | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) | ||||||
|  |  *                         Toshiba America Electronics Components, Inc. | ||||||
|  |  * | ||||||
|  |  * $Id: nand_ecc.c,v 1.14 2004/06/16 15:34:37 gleixner Exp $ | ||||||
|  |  * | ||||||
|  |  * This file 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 or (at your option) any | ||||||
|  |  * later version. | ||||||
|  |  * | ||||||
|  |  * This file 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 file; if not, write to the Free Software Foundation, Inc., | ||||||
|  |  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||||||
|  |  * | ||||||
|  |  * As a special exception, if other files instantiate templates or use | ||||||
|  |  * macros or inline functions from these files, or you compile these | ||||||
|  |  * files and link them with other works to produce a work based on these | ||||||
|  |  * files, these files do not by themselves cause the resulting work to be | ||||||
|  |  * covered by the GNU General Public License. However the source code for | ||||||
|  |  * these files must still be made available in accordance with section (3) | ||||||
|  |  * of the GNU General Public License. | ||||||
|  |  * | ||||||
|  |  * This exception does not invalidate any other reasons why a work based on | ||||||
|  |  * this file might be covered by the GNU General Public License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <common.h> | ||||||
|  | 
 | ||||||
|  | #ifdef CONFIG_NEW_NAND_CODE | ||||||
|  | #if (CONFIG_COMMANDS & CFG_CMD_NAND) | ||||||
|  | 
 | ||||||
|  | #include<linux/mtd/mtd.h> | ||||||
|  | /*
 | ||||||
|  |  * 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 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * nand_trans_result - [GENERIC] create non-inverted ECC | ||||||
|  |  * @reg2:	line parity reg 2 | ||||||
|  |  * @reg3:	line parity reg 3 | ||||||
|  |  * @ecc_code:	ecc | ||||||
|  |  * | ||||||
|  |  * Creates non-inverted ECC code from line parity | ||||||
|  |  */ | ||||||
|  | static void nand_trans_result(u_char reg2, u_char reg3, | ||||||
|  | 	u_char *ecc_code) | ||||||
|  | { | ||||||
|  | 	u_char a, b, i, tmp1, tmp2; | ||||||
|  | 
 | ||||||
|  | 	/* Initialize variables */ | ||||||
|  | 	a = b = 0x80; | ||||||
|  | 	tmp1 = tmp2 = 0; | ||||||
|  | 
 | ||||||
|  | 	/* Calculate first ECC byte */ | ||||||
|  | 	for (i = 0; i < 4; i++) { | ||||||
|  | 		if (reg3 & a)		/* LP15,13,11,9 --> ecc_code[0] */ | ||||||
|  | 			tmp1 |= b; | ||||||
|  | 		b >>= 1; | ||||||
|  | 		if (reg2 & a)		/* LP14,12,10,8 --> ecc_code[0] */ | ||||||
|  | 			tmp1 |= b; | ||||||
|  | 		b >>= 1; | ||||||
|  | 		a >>= 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Calculate second ECC byte */ | ||||||
|  | 	b = 0x80; | ||||||
|  | 	for (i = 0; i < 4; i++) { | ||||||
|  | 		if (reg3 & a)		/* LP7,5,3,1 --> ecc_code[1] */ | ||||||
|  | 			tmp2 |= b; | ||||||
|  | 		b >>= 1; | ||||||
|  | 		if (reg2 & a)		/* LP6,4,2,0 --> ecc_code[1] */ | ||||||
|  | 			tmp2 |= b; | ||||||
|  | 		b >>= 1; | ||||||
|  | 		a >>= 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Store two of the ECC bytes */ | ||||||
|  | 	ecc_code[0] = tmp1; | ||||||
|  | 	ecc_code[1] = tmp2; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code for 256 byte block | ||||||
|  |  * @mtd:	MTD block structure | ||||||
|  |  * @dat:	raw data | ||||||
|  |  * @ecc_code:	buffer for ECC | ||||||
|  |  */ | ||||||
|  | int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) | ||||||
|  | { | ||||||
|  | 	u_char idx, reg1, reg2, reg3; | ||||||
|  | 	int j; | ||||||
|  | 
 | ||||||
|  | 	/* Initialize variables */ | ||||||
|  | 	reg1 = reg2 = reg3 = 0; | ||||||
|  | 	ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; | ||||||
|  | 
 | ||||||
|  | 	/* Build up column parity */ | ||||||
|  | 	for(j = 0; j < 256; j++) { | ||||||
|  | 
 | ||||||
|  | 		/* Get CP0 - CP5 from table */ | ||||||
|  | 		idx = nand_ecc_precalc_table[dat[j]]; | ||||||
|  | 		reg1 ^= (idx & 0x3f); | ||||||
|  | 
 | ||||||
|  | 		/* All bit XOR = 1 ? */ | ||||||
|  | 		if (idx & 0x40) { | ||||||
|  | 			reg3 ^= (u_char) j; | ||||||
|  | 			reg2 ^= ~((u_char) j); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Create non-inverted ECC code from line parity */ | ||||||
|  | 	nand_trans_result(reg2, reg3, ecc_code); | ||||||
|  | 
 | ||||||
|  | 	/* Calculate final ECC code */ | ||||||
|  | 	ecc_code[0] = ~ecc_code[0]; | ||||||
|  | 	ecc_code[1] = ~ecc_code[1]; | ||||||
|  | 	ecc_code[2] = ((~reg1) << 2) | 0x03; | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * nand_correct_data - [NAND Interface] Detect and correct bit error(s) | ||||||
|  |  * @mtd:	MTD block structure | ||||||
|  |  * @dat:	raw data read from the chip | ||||||
|  |  * @read_ecc:	ECC from the chip | ||||||
|  |  * @calc_ecc:	the ECC calculated from raw data | ||||||
|  |  * | ||||||
|  |  * Detect and correct a 1 bit error for 256 byte block | ||||||
|  |  */ | ||||||
|  | int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) | ||||||
|  | { | ||||||
|  | 	u_char a, b, c, d1, d2, d3, add, bit, i; | ||||||
|  | 
 | ||||||
|  | 	/* Do error detection */ | ||||||
|  | 	d1 = calc_ecc[0] ^ read_ecc[0]; | ||||||
|  | 	d2 = calc_ecc[1] ^ read_ecc[1]; | ||||||
|  | 	d3 = calc_ecc[2] ^ read_ecc[2]; | ||||||
|  | 
 | ||||||
|  | 	if ((d1 | d2 | d3) == 0) { | ||||||
|  | 		/* No errors */ | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		a = (d1 ^ (d1 >> 1)) & 0x55; | ||||||
|  | 		b = (d2 ^ (d2 >> 1)) & 0x55; | ||||||
|  | 		c = (d3 ^ (d3 >> 1)) & 0x54; | ||||||
|  | 
 | ||||||
|  | 		/* Found and will correct single bit error in the data */ | ||||||
|  | 		if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { | ||||||
|  | 			c = 0x80; | ||||||
|  | 			add = 0; | ||||||
|  | 			a = 0x80; | ||||||
|  | 			for (i=0; i<4; i++) { | ||||||
|  | 				if (d1 & c) | ||||||
|  | 					add |= a; | ||||||
|  | 				c >>= 2; | ||||||
|  | 				a >>= 1; | ||||||
|  | 			} | ||||||
|  | 			c = 0x80; | ||||||
|  | 			for (i=0; i<4; i++) { | ||||||
|  | 				if (d2 & c) | ||||||
|  | 					add |= a; | ||||||
|  | 				c >>= 2; | ||||||
|  | 				a >>= 1; | ||||||
|  | 			} | ||||||
|  | 			bit = 0; | ||||||
|  | 			b = 0x04; | ||||||
|  | 			c = 0x80; | ||||||
|  | 			for (i=0; i<3; i++) { | ||||||
|  | 				if (d3 & c) | ||||||
|  | 					bit |= b; | ||||||
|  | 				c >>= 2; | ||||||
|  | 				b >>= 1; | ||||||
|  | 			} | ||||||
|  | 			b = 0x01; | ||||||
|  | 			a = dat[add]; | ||||||
|  | 			a ^= (b << bit); | ||||||
|  | 			dat[add] = a; | ||||||
|  | 			return 1; | ||||||
|  | 		} else { | ||||||
|  | 			i = 0; | ||||||
|  | 			while (d1) { | ||||||
|  | 				if (d1 & 0x01) | ||||||
|  | 					++i; | ||||||
|  | 				d1 >>= 1; | ||||||
|  | 			} | ||||||
|  | 			while (d2) { | ||||||
|  | 				if (d2 & 0x01) | ||||||
|  | 					++i; | ||||||
|  | 				d2 >>= 1; | ||||||
|  | 			} | ||||||
|  | 			while (d3) { | ||||||
|  | 				if (d3 & 0x01) | ||||||
|  | 					++i; | ||||||
|  | 				d3 >>= 1; | ||||||
|  | 			} | ||||||
|  | 			if (i == 1) { | ||||||
|  | 				/* ECC Code Error Correction */ | ||||||
|  | 				read_ecc[0] = calc_ecc[0]; | ||||||
|  | 				read_ecc[1] = calc_ecc[1]; | ||||||
|  | 				read_ecc[2] = calc_ecc[2]; | ||||||
|  | 				return 2; | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 				/* Uncorrectable Error */ | ||||||
|  | 				return -1; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Should never happen */ | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif	/* CONFIG_COMMANDS & CFG_CMD_NAND */ | ||||||
|  | #endif /* CONFIG_NEW_NAND_CODE */ | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,131 @@ | ||||||
|  | /*
 | ||||||
|  |  *  drivers/mtd/nandids.c | ||||||
|  |  * | ||||||
|  |  *  Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) | ||||||
|  |   * | ||||||
|  |  * $Id: nand_ids.c,v 1.10 2004/05/26 13:40:12 gleixner Exp $ | ||||||
|  |  * | ||||||
|  |  * This program is free software; you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License version 2 as | ||||||
|  |  * published by the Free Software Foundation. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <common.h> | ||||||
|  | 
 | ||||||
|  | #ifdef CONFIG_NEW_NAND_CODE | ||||||
|  | #if (CONFIG_COMMANDS & CFG_CMD_NAND) | ||||||
|  | 
 | ||||||
|  | #include <linux/mtd/nand.h> | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | *	Chip ID list | ||||||
|  | * | ||||||
|  | *	Name. ID code, pagesize, chipsize in MegaByte, eraseblock size, | ||||||
|  | *	options | ||||||
|  | * | ||||||
|  | * 	Pagesize; 0, 256, 512 | ||||||
|  | *	0 	get this information from the extended chip ID | ||||||
|  | +	256	256 Byte page size | ||||||
|  | *	512	512 Byte page size | ||||||
|  | */ | ||||||
|  | struct nand_flash_dev nand_flash_ids[] = { | ||||||
|  | 	{"NAND 1MiB 5V 8-bit", 		0x6e, 256, 1, 0x1000, 0}, | ||||||
|  | 	{"NAND 2MiB 5V 8-bit", 		0x64, 256, 2, 0x1000, 0}, | ||||||
|  | 	{"NAND 4MiB 5V 8-bit", 		0x6b, 512, 4, 0x2000, 0}, | ||||||
|  | 	{"NAND 1MiB 3,3V 8-bit", 	0xe8, 256, 1, 0x1000, 0}, | ||||||
|  | 	{"NAND 1MiB 3,3V 8-bit", 	0xec, 256, 1, 0x1000, 0}, | ||||||
|  | 	{"NAND 2MiB 3,3V 8-bit", 	0xea, 256, 2, 0x1000, 0}, | ||||||
|  | 	{"NAND 4MiB 3,3V 8-bit", 	0xd5, 512, 4, 0x2000, 0}, | ||||||
|  | 	{"NAND 4MiB 3,3V 8-bit", 	0xe3, 512, 4, 0x2000, 0}, | ||||||
|  | 	{"NAND 4MiB 3,3V 8-bit", 	0xe5, 512, 4, 0x2000, 0}, | ||||||
|  | 	{"NAND 8MiB 3,3V 8-bit", 	0xd6, 512, 8, 0x2000, 0}, | ||||||
|  | 
 | ||||||
|  | 	{"NAND 8MiB 1,8V 8-bit", 	0x39, 512, 8, 0x2000, 0}, | ||||||
|  | 	{"NAND 8MiB 3,3V 8-bit", 	0xe6, 512, 8, 0x2000, 0}, | ||||||
|  | 	{"NAND 8MiB 1,8V 16-bit", 	0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16}, | ||||||
|  | 	{"NAND 8MiB 3,3V 16-bit", 	0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16}, | ||||||
|  | 
 | ||||||
|  | 	{"NAND 16MiB 1,8V 8-bit", 	0x33, 512, 16, 0x4000, 0}, | ||||||
|  | 	{"NAND 16MiB 3,3V 8-bit", 	0x73, 512, 16, 0x4000, 0}, | ||||||
|  | 	{"NAND 16MiB 1,8V 16-bit", 	0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16}, | ||||||
|  | 	{"NAND 16MiB 3,3V 16-bit", 	0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16}, | ||||||
|  | 
 | ||||||
|  | 	{"NAND 32MiB 1,8V 8-bit", 	0x35, 512, 32, 0x4000, 0}, | ||||||
|  | 	{"NAND 32MiB 3,3V 8-bit", 	0x75, 512, 32, 0x4000, 0}, | ||||||
|  | 	{"NAND 32MiB 1,8V 16-bit", 	0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16}, | ||||||
|  | 	{"NAND 32MiB 3,3V 16-bit", 	0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16}, | ||||||
|  | 
 | ||||||
|  | 	{"NAND 64MiB 1,8V 8-bit", 	0x36, 512, 64, 0x4000, 0}, | ||||||
|  | 	{"NAND 64MiB 3,3V 8-bit", 	0x76, 512, 64, 0x4000, 0}, | ||||||
|  | 	{"NAND 64MiB 1,8V 16-bit", 	0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16}, | ||||||
|  | 	{"NAND 64MiB 3,3V 16-bit", 	0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, | ||||||
|  | 
 | ||||||
|  | 	{"NAND 128MiB 1,8V 8-bit", 	0x78, 512, 128, 0x4000, 0}, | ||||||
|  | 	{"NAND 128MiB 3,3V 8-bit", 	0x79, 512, 128, 0x4000, 0}, | ||||||
|  | 	{"NAND 128MiB 1,8V 16-bit", 	0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16}, | ||||||
|  | 	{"NAND 128MiB 3,3V 16-bit", 	0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, | ||||||
|  | 
 | ||||||
|  | 	{"NAND 256MiB 3,3V 8-bit", 	0x71, 512, 256, 0x4000, 0}, | ||||||
|  | 
 | ||||||
|  | 	{"NAND 512MiB 3,3V 8-bit", 	0xDC, 512, 512, 0x4000, 0}, | ||||||
|  | 
 | ||||||
|  | 	/* These are the new chips with large page size. The pagesize
 | ||||||
|  | 	* and the erasesize is determined from the extended id bytes | ||||||
|  | 	*/ | ||||||
|  | 	/* 1 Gigabit */ | ||||||
|  | 	{"NAND 128MiB 1,8V 8-bit", 	0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 128MiB 3,3V 8-bit", 	0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 128MiB 1,8V 16-bit", 	0xB1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 128MiB 3,3V 16-bit", 	0xC1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | ||||||
|  | 
 | ||||||
|  | 	/* 2 Gigabit */ | ||||||
|  | 	{"NAND 256MiB 1,8V 8-bit", 	0xAA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 256MiB 3,3V 8-bit", 	0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 256MiB 1,8V 16-bit", 	0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 256MiB 3,3V 16-bit", 	0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | ||||||
|  | 
 | ||||||
|  | 	/* 4 Gigabit */ | ||||||
|  | 	{"NAND 512MiB 1,8V 8-bit", 	0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 512MiB 3,3V 8-bit", 	0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 512MiB 1,8V 16-bit", 	0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 512MiB 3,3V 16-bit", 	0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | ||||||
|  | 
 | ||||||
|  | 	/* 8 Gigabit */ | ||||||
|  | 	{"NAND 1GiB 1,8V 8-bit", 	0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 1GiB 3,3V 8-bit", 	0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 1GiB 1,8V 16-bit", 	0xB3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 1GiB 3,3V 16-bit", 	0xC3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | ||||||
|  | 
 | ||||||
|  | 	/* 16 Gigabit */ | ||||||
|  | 	{"NAND 2GiB 1,8V 8-bit", 	0xA5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 2GiB 3,3V 8-bit", 	0xD5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 2GiB 1,8V 16-bit", 	0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | ||||||
|  | 	{"NAND 2GiB 3,3V 16-bit", 	0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, | ||||||
|  | 
 | ||||||
|  | 	/* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout !
 | ||||||
|  | 	 * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes | ||||||
|  | 	 * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 | ||||||
|  | 	 * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go | ||||||
|  | 	 * There are more speed improvements for reads and writes possible, but not implemented now | ||||||
|  | 	 */ | ||||||
|  | 	{"AND 128MiB 3,3V 8-bit",	0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY}, | ||||||
|  | 
 | ||||||
|  | 	{NULL,} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | *	Manufacturer ID list | ||||||
|  | */ | ||||||
|  | struct nand_manufacturers nand_manuf_ids[] = { | ||||||
|  | 	{NAND_MFR_TOSHIBA, "Toshiba"}, | ||||||
|  | 	{NAND_MFR_SAMSUNG, "Samsung"}, | ||||||
|  | 	{NAND_MFR_FUJITSU, "Fujitsu"}, | ||||||
|  | 	{NAND_MFR_NATIONAL, "National"}, | ||||||
|  | 	{NAND_MFR_RENESAS, "Renesas"}, | ||||||
|  | 	{NAND_MFR_STMICRO, "ST Micro"}, | ||||||
|  | 	{0x0, "Unknown"} | ||||||
|  | }; | ||||||
|  | #endif | ||||||
|  | #endif /* CONFIG_NEW_NAND_CODE */ | ||||||
|  | 
 | ||||||
|  | @ -143,7 +143,7 @@ | ||||||
| /* keeps pointer to currentlu processed partition */ | /* keeps pointer to currentlu processed partition */ | ||||||
| static struct part_info *current_part; | static struct part_info *current_part; | ||||||
| 
 | 
 | ||||||
| #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) | #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) | ||||||
| /*
 | /*
 | ||||||
|  * Support for jffs2 on top of NAND-flash |  * Support for jffs2 on top of NAND-flash | ||||||
|  * |  * | ||||||
|  | @ -290,7 +290,7 @@ static inline void *get_fl_mem(u32 off, u32 size, void *ext_buf) | ||||||
| 		return get_fl_mem_nor(off); | 		return get_fl_mem_nor(off); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) | #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) | ||||||
| 	if (id->type == MTD_DEV_TYPE_NAND) | 	if (id->type == MTD_DEV_TYPE_NAND) | ||||||
| 		return get_fl_mem_nand(off, size, ext_buf); | 		return get_fl_mem_nand(off, size, ext_buf); | ||||||
| #endif | #endif | ||||||
|  | @ -308,7 +308,7 @@ static inline void *get_node_mem(u32 off) | ||||||
| 		return get_node_mem_nor(off); | 		return get_node_mem_nor(off); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) | #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) | ||||||
| 	if (id->type == MTD_DEV_TYPE_NAND) | 	if (id->type == MTD_DEV_TYPE_NAND) | ||||||
| 		return get_node_mem_nand(off); | 		return get_node_mem_nand(off); | ||||||
| #endif | #endif | ||||||
|  | @ -319,7 +319,7 @@ static inline void *get_node_mem(u32 off) | ||||||
| 
 | 
 | ||||||
| static inline void put_fl_mem(void *buf) | static inline void put_fl_mem(void *buf) | ||||||
| { | { | ||||||
| #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) | #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) | ||||||
| 	struct mtdids *id = current_part->dev->id; | 	struct mtdids *id = current_part->dev->id; | ||||||
| 
 | 
 | ||||||
| 	if (id->type == MTD_DEV_TYPE_NAND) | 	if (id->type == MTD_DEV_TYPE_NAND) | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -0,0 +1,133 @@ | ||||||
|  | #ifndef jffs2_private_h | ||||||
|  | #define jffs2_private_h | ||||||
|  | 
 | ||||||
|  | #include <jffs2/jffs2.h> | ||||||
|  | 
 | ||||||
|  | struct b_node { | ||||||
|  | 	struct b_node *next; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct b_inode { | ||||||
|  | 	struct b_inode *next; | ||||||
|  | 	u32 offset;	/* physical offset to beginning of real inode */ | ||||||
|  | 	u32 version; | ||||||
|  | 	u32 ino; | ||||||
|  | 	u32 isize; | ||||||
|  | 	u32 csize; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct b_dirent { | ||||||
|  | 	struct b_dirent *next; | ||||||
|  | 	u32 offset;	/* physical offset to beginning of real dirent */ | ||||||
|  | 	u32 version; | ||||||
|  | 	u32 pino; | ||||||
|  | 	u32 ino; | ||||||
|  | 	unsigned int nhash; | ||||||
|  | 	unsigned char nsize; | ||||||
|  | 	unsigned char type; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct b_list { | ||||||
|  | 	struct b_node *listTail; | ||||||
|  | 	struct b_node *listHead; | ||||||
|  | 	unsigned int listCount; | ||||||
|  | 	struct mem_block *listMemBase; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct b_lists { | ||||||
|  | 	char *partOffset; | ||||||
|  | 	struct b_list dir; | ||||||
|  | 	struct b_list frag; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct b_compr_info { | ||||||
|  | 	u32 num_frags; | ||||||
|  | 	u32 compr_sum; | ||||||
|  | 	u32 decompr_sum; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct b_jffs2_info { | ||||||
|  | 	struct b_compr_info compr_info[JFFS2_NUM_COMPR]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static inline int | ||||||
|  | hdr_crc(struct jffs2_unknown_node *node) | ||||||
|  | { | ||||||
|  | #if 1 | ||||||
|  | 	u32 crc = crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4); | ||||||
|  | #else | ||||||
|  | 	/* what's the semantics of this? why is this here? */ | ||||||
|  | 	u32 crc = crc32_no_comp(~0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4); | ||||||
|  | 
 | ||||||
|  | 	crc ^= ~0; | ||||||
|  | #endif | ||||||
|  | 	if (node->hdr_crc != crc) { | ||||||
|  | 		return 0; | ||||||
|  | 	} else { | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline int | ||||||
|  | dirent_crc(struct jffs2_raw_dirent *node) | ||||||
|  | { | ||||||
|  | 	if (node->node_crc != crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_raw_dirent) - 8)) { | ||||||
|  | 		return 0; | ||||||
|  | 	} else { | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline int | ||||||
|  | dirent_name_crc(struct jffs2_raw_dirent *node) | ||||||
|  | { | ||||||
|  | 	if (node->name_crc != crc32_no_comp(0, (unsigned char *)&(node->name), node->nsize)) { | ||||||
|  | 		return 0; | ||||||
|  | 	} else { | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline int | ||||||
|  | inode_crc(struct jffs2_raw_inode *node) | ||||||
|  | { | ||||||
|  | 	if (node->node_crc != crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_raw_inode) - 8)) { | ||||||
|  | 		return 0; | ||||||
|  | 	} else { | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Borrowed from include/linux/dcache.h */ | ||||||
|  | 
 | ||||||
|  | /* Name hashing routines. Initial hash value */ | ||||||
|  | /* Hash courtesy of the R5 hash in reiserfs modulo sign bits */ | ||||||
|  | #define init_name_hash()		0 | ||||||
|  | 
 | ||||||
|  | /* partial hash update function. Assume roughly 4 bits per character */ | ||||||
|  | static inline unsigned long | ||||||
|  | partial_name_hash(unsigned long c, unsigned long prevhash) | ||||||
|  | { | ||||||
|  | 	return (prevhash + (c << 4) + (c >> 4)) * 11; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Finally: cut down the number of bits to a int value (and try to avoid | ||||||
|  |  * losing bits) | ||||||
|  |  */ | ||||||
|  | static inline unsigned long end_name_hash(unsigned long hash) | ||||||
|  | { | ||||||
|  | 	return (unsigned int) hash; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Compute the hash for a name string. */ | ||||||
|  | static inline unsigned int | ||||||
|  | full_name_hash(const unsigned char *name, unsigned int len) | ||||||
|  | { | ||||||
|  | 	unsigned long hash = init_name_hash(); | ||||||
|  | 	while (len--) | ||||||
|  | 		hash = partial_name_hash(*name++, hash); | ||||||
|  | 	return end_name_hash(hash); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif /* jffs2_private.h */ | ||||||
|  | @ -58,6 +58,14 @@ extern void __raw_readsl(unsigned int addr, void *data, int longlen); | ||||||
| #define __raw_readw(a)			__arch_getw(a) | #define __raw_readw(a)			__arch_getw(a) | ||||||
| #define __raw_readl(a)			__arch_getl(a) | #define __raw_readl(a)			__arch_getl(a) | ||||||
| 
 | 
 | ||||||
|  | #define writeb(v,a)			__arch_putb(v,a) | ||||||
|  | #define writew(v,a)			__arch_putw(v,a) | ||||||
|  | #define writel(v,a)			__arch_putl(v,a) | ||||||
|  | 
 | ||||||
|  | #define readb(a)			__arch_getb(a) | ||||||
|  | #define readw(a)			__arch_getw(a) | ||||||
|  | #define readl(a)			__arch_getl(a) | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * The compiler seems to be incapable of optimising constants |  * The compiler seems to be incapable of optimising constants | ||||||
|  * properly.  Spell it out to the compiler in some cases. |  * properly.  Spell it out to the compiler in some cases. | ||||||
|  |  | ||||||
|  | @ -188,10 +188,14 @@ | ||||||
|  * NAND-FLASH stuff |  * NAND-FLASH stuff | ||||||
|  *----------------------------------------------------------------------- |  *----------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
|  | 
 | ||||||
|  | /* Use the new NAND code. (BOARDLIBS = drivers/nand/libnand.a required) */ | ||||||
|  | #define CONFIG_NEW_NAND_CODE | ||||||
| #define CFG_NAND0_BASE 0xFF400000 | #define CFG_NAND0_BASE 0xFF400000 | ||||||
| #define CFG_NAND1_BASE 0xFF000000 | #define CFG_NAND1_BASE 0xFF000000 | ||||||
| 
 | #define CFG_NAND_BASE_LIST	{ CFG_NAND0_BASE, CFG_NAND1_BASE } | ||||||
| #define CFG_MAX_NAND_DEVICE	2	/* Max number of NAND devices		*/ | #define NAND_BIG_DELAY_US	25 | ||||||
|  | #define CFG_MAX_NAND_DEVICE	2	/* Max number of NAND devices */ | ||||||
| #define SECTORSIZE 512 | #define SECTORSIZE 512 | ||||||
| #define NAND_NO_RB | #define NAND_NO_RB | ||||||
| 
 | 
 | ||||||
|  | @ -213,6 +217,83 @@ | ||||||
| #define CFG_NAND1_ALE (0x80000000 >> 16)  /* our ALE is GPIO16 */ | #define CFG_NAND1_ALE (0x80000000 >> 16)  /* our ALE is GPIO16 */ | ||||||
| #define CFG_NAND1_RDY (0x80000000 >> 31)  /* our RDY is GPIO31 */ | #define CFG_NAND1_RDY (0x80000000 >> 31)  /* our RDY is GPIO31 */ | ||||||
| 
 | 
 | ||||||
|  | #ifdef CONFIG_NEW_NAND_CODE | ||||||
|  | #define MACRO_NAND_DISABLE_CE(nandptr) do \ | ||||||
|  | { \ | ||||||
|  | 	switch((unsigned long)nandptr) \ | ||||||
|  | 	{ \ | ||||||
|  | 	    case CFG_NAND0_BASE: \ | ||||||
|  | 		out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND0_CE); \ | ||||||
|  | 		break; \ | ||||||
|  | 	    case CFG_NAND1_BASE: \ | ||||||
|  | 		out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND1_CE); \ | ||||||
|  | 		break; \ | ||||||
|  | 	} \ | ||||||
|  | } while(0) | ||||||
|  | 
 | ||||||
|  | #define MACRO_NAND_ENABLE_CE(nandptr) do \ | ||||||
|  | { \ | ||||||
|  | 	switch((unsigned long)nandptr) \ | ||||||
|  | 	{ \ | ||||||
|  | 	    case CFG_NAND0_BASE: \ | ||||||
|  | 		out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_NAND0_CE); \ | ||||||
|  | 		break; \ | ||||||
|  | 	    case CFG_NAND1_BASE: \ | ||||||
|  | 		out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_NAND1_CE); \ | ||||||
|  | 		break; \ | ||||||
|  | 	} \ | ||||||
|  | } while(0) | ||||||
|  | 
 | ||||||
|  | #define MACRO_NAND_CTL_CLRALE(nandptr) do \ | ||||||
|  | { \ | ||||||
|  | 	switch((unsigned long)nandptr) \ | ||||||
|  | 	{ \ | ||||||
|  | 	    case CFG_NAND0_BASE: \ | ||||||
|  | 		out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_NAND0_ALE); \ | ||||||
|  | 		break; \ | ||||||
|  | 	    case CFG_NAND1_BASE: \ | ||||||
|  | 		out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_NAND1_ALE); \ | ||||||
|  | 		break; \ | ||||||
|  | 	} \ | ||||||
|  | } while(0) | ||||||
|  | 
 | ||||||
|  | #define MACRO_NAND_CTL_SETALE(nandptr) do \ | ||||||
|  | { \ | ||||||
|  | 	switch((unsigned long)nandptr) \ | ||||||
|  | 	{ \ | ||||||
|  | 	    case CFG_NAND0_BASE: \ | ||||||
|  | 		out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND0_ALE); \ | ||||||
|  | 		break; \ | ||||||
|  | 	    case CFG_NAND1_BASE: \ | ||||||
|  | 		out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND1_ALE); \ | ||||||
|  | 		break; \ | ||||||
|  | 	} \ | ||||||
|  | } while(0) | ||||||
|  | 
 | ||||||
|  | #define MACRO_NAND_CTL_CLRCLE(nandptr) do \ | ||||||
|  | { \ | ||||||
|  | 	switch((unsigned long)nandptr) \ | ||||||
|  | 	{ \ | ||||||
|  | 	    case CFG_NAND0_BASE: \ | ||||||
|  | 		out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_NAND0_CLE); \ | ||||||
|  | 		break; \ | ||||||
|  | 	    case CFG_NAND1_BASE: \ | ||||||
|  | 		out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_NAND1_CLE); \ | ||||||
|  | 		break; \ | ||||||
|  | 	} \ | ||||||
|  | } while(0) | ||||||
|  | 
 | ||||||
|  | #define MACRO_NAND_CTL_SETCLE(nandptr) do { \ | ||||||
|  | 	switch((unsigned long)nandptr) { \ | ||||||
|  | 	case CFG_NAND0_BASE: \ | ||||||
|  | 		out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND0_CLE); \ | ||||||
|  | 		break; \ | ||||||
|  | 	case CFG_NAND1_BASE: \ | ||||||
|  | 		out32(GPIO0_OR, in32(GPIO0_OR) | CFG_NAND1_CLE); \ | ||||||
|  | 		break; \ | ||||||
|  | 	} \ | ||||||
|  | } while(0) | ||||||
|  | #else | ||||||
| #define NAND_DISABLE_CE(nand) do \ | #define NAND_DISABLE_CE(nand) do \ | ||||||
| { \ | { \ | ||||||
| 	switch((unsigned long)(((struct nand_chip *)nand)->IO_ADDR)) \ | 	switch((unsigned long)(((struct nand_chip *)nand)->IO_ADDR)) \ | ||||||
|  | @ -288,6 +369,7 @@ | ||||||
| 		break; \ | 		break; \ | ||||||
| 	} \ | 	} \ | ||||||
| } while(0) | } while(0) | ||||||
|  | #endif /* !CONFIG_NEW_NAND_CODE */ | ||||||
| 
 | 
 | ||||||
| #ifdef NAND_NO_RB | #ifdef NAND_NO_RB | ||||||
| /* constant delay (see also tR in the datasheet) */ | /* constant delay (see also tR in the datasheet) */ | ||||||
|  | @ -338,16 +420,16 @@ | ||||||
| #define CFG_SDRAM_BASE		0x00000000 | #define CFG_SDRAM_BASE		0x00000000 | ||||||
| 
 | 
 | ||||||
| /* Reserve 256 kB for Monitor	*/ | /* Reserve 256 kB for Monitor	*/ | ||||||
|  | /*
 | ||||||
| #define CFG_FLASH_BASE		0xFFFC0000 | #define CFG_FLASH_BASE		0xFFFC0000 | ||||||
| #define CFG_MONITOR_BASE	CFG_FLASH_BASE | #define CFG_MONITOR_BASE	CFG_FLASH_BASE | ||||||
| #define CFG_MONITOR_LEN		(256 * 1024) | #define CFG_MONITOR_LEN		(256 * 1024) | ||||||
|  | */ | ||||||
| 
 | 
 | ||||||
| /* Reserve 320 kB for Monitor	*/ | /* Reserve 320 kB for Monitor	*/ | ||||||
| /*
 |  | ||||||
| #define CFG_FLASH_BASE		0xFFFB0000 | #define CFG_FLASH_BASE		0xFFFB0000 | ||||||
| #define CFG_MONITOR_BASE	CFG_FLASH_BASE | #define CFG_MONITOR_BASE	CFG_FLASH_BASE | ||||||
| #define CFG_MONITOR_LEN		(320 * 1024) | #define CFG_MONITOR_LEN		(320 * 1024) | ||||||
| */ |  | ||||||
| 
 | 
 | ||||||
| #define CFG_MALLOC_LEN		(256 * 1024)	/* Reserve 256 kB for malloc()	*/ | #define CFG_MALLOC_LEN		(256 * 1024)	/* Reserve 256 kB for malloc()	*/ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,265 @@ | ||||||
|  | /*
 | ||||||
|  |  * (C) Copyright 2005 2N TELEKOMUNIKACE, Ladislav Michl | ||||||
|  |  * | ||||||
|  |  * Configuation settings for the TI OMAP NetStar board. | ||||||
|  |  * | ||||||
|  |  * 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 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __CONFIG_H | ||||||
|  | #define __CONFIG_H | ||||||
|  | 
 | ||||||
|  | #include <configs/omap1510.h> | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * High Level Configuration Options | ||||||
|  |  * (easy to change) | ||||||
|  |  */ | ||||||
|  | #define CONFIG_ARM925T	1		/* This is an arm925t CPU */ | ||||||
|  | #define CONFIG_OMAP	1		/* in a TI OMAP core */ | ||||||
|  | #define CONFIG_OMAP1510 1		/* which is in a 5910 */ | ||||||
|  | 
 | ||||||
|  | /* Input clock of PLL */ | ||||||
|  | #define CONFIG_SYS_CLK_FREQ	150000000	/* 150MHz input clock */ | ||||||
|  | #define CONFIG_XTAL_FREQ	12000000 | ||||||
|  | 
 | ||||||
|  | #undef CONFIG_USE_IRQ			/* we don't need IRQ/FIQ stuff */ | ||||||
|  | 
 | ||||||
|  | #define CONFIG_MISC_INIT_R		/* There is nothing to really init */ | ||||||
|  | #define BOARD_LATE_INIT			/* but we flash the LEDs here */ | ||||||
|  | 
 | ||||||
|  | #define CONFIG_CMDLINE_TAG		1	/* enable passing of ATAGs */ | ||||||
|  | #define CONFIG_SETUP_MEMORY_TAGS	1 | ||||||
|  | #define CONFIG_INITRD_TAG		1 | ||||||
|  | 
 | ||||||
|  | #define CFG_DEVICE_NULLDEV		1	/* enable null device */ | ||||||
|  | #define CONFIG_SILENT_CONSOLE		1	/* enable silent startup */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Physical Memory Map | ||||||
|  |  */ | ||||||
|  | #define CONFIG_NR_DRAM_BANKS	1		/* we have 1 bank of DRAM */ | ||||||
|  | #define PHYS_SDRAM_1		0x10000000	/* SDRAM Bank #1 */ | ||||||
|  | #define PHYS_FLASH_1		0x00000000	/* Flash Bank #1 */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * FLASH organization | ||||||
|  |  */ | ||||||
|  | #define CFG_FLASH_BASE		PHYS_FLASH_1 | ||||||
|  | #define CFG_MAX_FLASH_BANKS	1 | ||||||
|  | #if (PHYS_SDRAM_1_SIZE == SZ_32M) | ||||||
|  | /*#if 1*/ | ||||||
|  | #define CFG_FLASH_CFI			/* Flash is CFI conformant */ | ||||||
|  | #define CFG_FLASH_CFI_DRIVER		/* Use the common driver */ | ||||||
|  | #define CFG_FLASH_EMPTY_INFO | ||||||
|  | #define CFG_MAX_FLASH_SECT	128 | ||||||
|  | #else | ||||||
|  | #define PHYS_FLASH_1_SIZE	SZ_1M | ||||||
|  | #define CFG_MAX_FLASH_SECT	19 | ||||||
|  | #define CFG_FLASH_ERASE_TOUT	(5*CFG_HZ) /* in ticks */ | ||||||
|  | #define CFG_FLASH_WRITE_TOUT	(5*CFG_HZ) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #define CFG_MONITOR_BASE	PHYS_FLASH_1 | ||||||
|  | #define CFG_MONITOR_LEN		SZ_256K | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Environment settings | ||||||
|  |  */ | ||||||
|  | #define CFG_ENV_IS_IN_FLASH | ||||||
|  | #define ENV_IS_SOLITARY | ||||||
|  | #define CFG_ENV_ADDR		0x4000 | ||||||
|  | #define CFG_ENV_SIZE		SZ_8K | ||||||
|  | #define CFG_ENV_SECT_SIZE	SZ_8K | ||||||
|  | #define CFG_ENV_ADDR_REDUND	0x6000 | ||||||
|  | #define CFG_ENV_SIZE_REDUND	CFG_ENV_SIZE | ||||||
|  | #define CONFIG_ENV_OVERWRITE | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Size of malloc() pool | ||||||
|  |  */ | ||||||
|  | #define CFG_GBL_DATA_SIZE	128	/* size in bytes reserved for initial data */ | ||||||
|  | /* XXX #define CFG_MALLOC_LEN		(SZ_64K - CFG_GBL_DATA_SIZE)*/ | ||||||
|  | #define CFG_MALLOC_LEN		SZ_4M | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * The stack size is set up in start.S using the settings below | ||||||
|  |  */ | ||||||
|  | /* XXX #define CONFIG_STACKSIZE	SZ_8K	/XXX* regular stack */ | ||||||
|  | #define CONFIG_STACKSIZE	SZ_1M	/* regular stack */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Hardware drivers | ||||||
|  |  */ | ||||||
|  | #define CONFIG_DRIVER_SMC91111 | ||||||
|  | #define CONFIG_SMC91111_BASE	0x04000300 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * NS16550 Configuration | ||||||
|  |  */ | ||||||
|  | #define CFG_NS16550 | ||||||
|  | #define CFG_NS16550_SERIAL | ||||||
|  | #define CFG_NS16550_REG_SIZE	(-4) | ||||||
|  | #define CFG_NS16550_CLK		(CONFIG_XTAL_FREQ)	/* can be 12M/32Khz or 48Mhz  */ | ||||||
|  | #define CFG_NS16550_COM1	OMAP1510_UART1_BASE	/* uart1 */ | ||||||
|  | 
 | ||||||
|  | #define CONFIG_CONS_INDEX	1 | ||||||
|  | #define CONFIG_BAUDRATE		115200 | ||||||
|  | #define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 } | ||||||
|  | 
 | ||||||
|  | /*#define CONFIG_SKIP_RELOCATE_UBOOT*/ | ||||||
|  | /*#define CONFIG_SKIP_LOWLEVEL_INIT */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * NAND flash | ||||||
|  |  */ | ||||||
|  | #define CFG_MAX_NAND_DEVICE	1 | ||||||
|  | #define CFG_NAND_BASE	0x04000000 + (2 << 23) | ||||||
|  | #define CONFIG_NEW_NAND_CODE | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * JFFS2 partitions (mtdparts command line support) | ||||||
|  |  */ | ||||||
|  | #define CONFIG_JFFS2_CMDLINE | ||||||
|  | #define MTDIDS_DEFAULT		"nor0=omapflash.0,nand0=omapnand.0" | ||||||
|  | #define MTDPARTS_DEFAULT	"mtdparts=omapflash.0:8k@16k(env),8k(r_env),448k@576k(u-boot);omapnand.0:48M(rootfs0),48M(rootfs1),-(data)" | ||||||
|  | 
 | ||||||
|  | #if 0 | ||||||
|  | #define CONFIG_COMMANDS		(CFG_CMD_BDI    | \ | ||||||
|  | 				 CFG_CMD_BOOTD  | \ | ||||||
|  | 				 CFG_CMD_DHCP   | \ | ||||||
|  | 				 CFG_CMD_ENV	| \ | ||||||
|  | 				 CFG_CMD_FLASH  | \ | ||||||
|  | 				 CFG_CMD_IMI    | \ | ||||||
|  | 				 CFG_CMD_LOADB  | \ | ||||||
|  | 				 CFG_CMD_NET    | \ | ||||||
|  | 				 CFG_CMD_MEMORY | \ | ||||||
|  | 				 CFG_CMD_PING   | \ | ||||||
|  | 				 CFG_CMD_RUN) | ||||||
|  | 
 | ||||||
|  | #else | ||||||
|  | #define CONFIG_COMMANDS		(CFG_CMD_BDI    | \ | ||||||
|  | 				 CFG_CMD_BOOTD  | \ | ||||||
|  | 				 CFG_CMD_DHCP   | \ | ||||||
|  | 				 CFG_CMD_ENV	| \ | ||||||
|  | 				 CFG_CMD_FLASH  | \ | ||||||
|  | 				 CFG_CMD_NAND	| \ | ||||||
|  | 				 CFG_CMD_IMI    | \ | ||||||
|  | 				 CFG_CMD_JFFS2	| \ | ||||||
|  | 				 CFG_CMD_LOADB  | \ | ||||||
|  | 				 CFG_CMD_NET    | \ | ||||||
|  | 				 CFG_CMD_MEMORY | \ | ||||||
|  | 				 CFG_CMD_PING   | \ | ||||||
|  | 				 CFG_CMD_RUN) | ||||||
|  | 
 | ||||||
|  | #define CONFIG_JFFS2_NAND	1	/* jffs2 on nand support */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #define CONFIG_BOOTP_MASK	CONFIG_BOOTP_DEFAULT | ||||||
|  | #define CONFIG_LOOPW | ||||||
|  | 
 | ||||||
|  | /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ | ||||||
|  | #include <cmd_confdefs.h> | ||||||
|  | 
 | ||||||
|  | #define CONFIG_BOOTDELAY	3 | ||||||
|  | #define CONFIG_ZERO_BOOTDELAY_CHECK	/* allow to break in always */ | ||||||
|  | #undef  CONFIG_BOOTARGS		/* the boot command will set bootargs*/ | ||||||
|  | #define CFG_AUTOLOAD		"n"		/* No autoload */ | ||||||
|  | #define CONFIG_BOOTCOMMAND	"run nboot" | ||||||
|  | #define CONFIG_PREBOOT		"run setup" | ||||||
|  | #define	CONFIG_EXTRA_ENV_SETTINGS				\ | ||||||
|  | 	"setup=setenv bootargs console=ttyS0,$baudrate "	\ | ||||||
|  | 		"$mtdparts\0"					\ | ||||||
|  | 	"ospart=0\0"						\ | ||||||
|  | 	"setpart="						\ | ||||||
|  | 	"if test -n $swapos; then "				\ | ||||||
|  | 		"if test $ospart -eq 0; then chpart nand0,1; else chpart nand0,0; fi; "\ | ||||||
|  | 		"setenv swapos; saveenv; "			\ | ||||||
|  | 	"else "							\ | ||||||
|  | 		"chpart nand0,$ospart; "			\ | ||||||
|  | 	"fi\0"							\ | ||||||
|  | 	"nfsargs=setenv bootargs $bootargs "			\ | ||||||
|  | 		"ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname::off " \ | ||||||
|  | 		"nfsroot=$rootpath root=/dev/nfs\0"		\ | ||||||
|  | 	"flashargs=run setpart;setenv bootargs $bootargs "	\ | ||||||
|  | 		"root=/dev/mtdblock$partition ro "		\ | ||||||
|  | 		"rootfstype=jffs2\0"				\ | ||||||
|  | 	"initrdargs=setenv bootargs $bootargs "			\ | ||||||
|  | 		"ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname::off\0" \ | ||||||
|  | 	"iboot=bootp;run initrdargs;tftp;bootm\0"		\ | ||||||
|  | 	"fboot=run flashargs;fsload /boot/uImage;bootm\0"	\ | ||||||
|  | 	"nboot=bootp;run nfsargs;tftp;bootm\0" | ||||||
|  | 
 | ||||||
|  | #if 0	/* feel free to disable for development */
 | ||||||
|  | #define	CONFIG_AUTOBOOT_KEYED		/* Enable password protection	*/ | ||||||
|  | #define CONFIG_AUTOBOOT_PROMPT	"\nNetStar PBX - boot in %d sec...\n" | ||||||
|  | #define CONFIG_AUTOBOOT_DELAY_STR	"R"	/* 1st "password"	*/ | ||||||
|  | #define CONFIG_BOOT_RETRY_TIME	30 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Miscellaneous configurable options | ||||||
|  |  */ | ||||||
|  | #define CFG_LONGHELP				/* undef to save memory		*/ | ||||||
|  | #define CFG_PROMPT		"# "		/* Monitor Command Prompt	*/ | ||||||
|  | #define CFG_CBSIZE		256		/* Console I/O Buffer Size	*/ | ||||||
|  | #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_HUSH_PARSER | ||||||
|  | #define CFG_PROMPT_HUSH_PS2	"> " | ||||||
|  | #define CONFIG_AUTO_COMPLETE | ||||||
|  | 
 | ||||||
|  | #define CFG_MEMTEST_START	PHYS_SDRAM_1 | ||||||
|  | #define CFG_MEMTEST_END		PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE | ||||||
|  | 
 | ||||||
|  | #undef	CFG_CLKS_IN_HZ		/* everything, incl board info, in Hz */ | ||||||
|  | 
 | ||||||
|  | #define CFG_LOAD_ADDR		PHYS_SDRAM_1 + 0x400000	/* default load address */ | ||||||
|  | 
 | ||||||
|  | /* The 1510 has 3 timers, they can be driven by the RefClk (12Mhz) or by DPLL1.
 | ||||||
|  |  * This time is further subdivided by a local divisor. | ||||||
|  |  */ | ||||||
|  | #define CFG_TIMERBASE		OMAP1510_TIMER1_BASE | ||||||
|  | #define CFG_PVT			7		/* 2^(pvt+1), divide by 256 */ | ||||||
|  | #define CFG_HZ			((CONFIG_SYS_CLK_FREQ)/(2 << CFG_PVT)) | ||||||
|  | 
 | ||||||
|  | #define OMAP5910_DPLL_DIV	1 | ||||||
|  | #define OMAP5910_DPLL_MUL	((CONFIG_SYS_CLK_FREQ * \ | ||||||
|  | 				 (1 << OMAP5910_DPLL_DIV)) / CONFIG_XTAL_FREQ) | ||||||
|  | 
 | ||||||
|  | #define OMAP5910_ARM_PER_DIV	2	/* CKL/4 */ | ||||||
|  | #define OMAP5910_LCD_DIV	2	/* CKL/4 */ | ||||||
|  | #define OMAP5910_ARM_DIV	0	/* CKL/1 */ | ||||||
|  | #define OMAP5910_DSP_DIV	0	/* CKL/1 */ | ||||||
|  | #define OMAP5910_TC_DIV		1	/* CKL/2 */ | ||||||
|  | #define OMAP5910_DSP_MMU_DIV	1	/* CKL/2 */ | ||||||
|  | #define OMAP5910_ARM_TIM_SEL	1	/* CKL used for MPU timers */ | ||||||
|  | 
 | ||||||
|  | #define OMAP5910_ARM_EN_CLK	0x03d6	/* 0000 0011 1101 0110b  Clock Enable */ | ||||||
|  | #define OMAP5910_ARM_CKCTL	((OMAP5910_ARM_PER_DIV)  |	\ | ||||||
|  | 				 (OMAP5910_LCD_DIV << 2) |	\ | ||||||
|  | 				 (OMAP5910_ARM_DIV << 4) |	\ | ||||||
|  | 				 (OMAP5910_DSP_DIV << 6) |	\ | ||||||
|  | 				 (OMAP5910_TC_DIV << 8) |	\ | ||||||
|  | 				 (OMAP5910_DSP_MMU_DIV << 10) |	\ | ||||||
|  | 				 (OMAP5910_ARM_TIM_SEL << 12)) | ||||||
|  | 
 | ||||||
|  | #endif	/* __CONFIG_H */ | ||||||
|  | @ -0,0 +1,44 @@ | ||||||
|  | #ifndef _LINUX_COMPAT_H_ | ||||||
|  | #define _LINUX_COMPAT_H_ | ||||||
|  | 
 | ||||||
|  | #define __user | ||||||
|  | #define __iomem | ||||||
|  | 
 | ||||||
|  | #define ndelay(x)	udelay(1) | ||||||
|  | 
 | ||||||
|  | #define printk	printf | ||||||
|  | 
 | ||||||
|  | #define KERN_EMERG | ||||||
|  | #define KERN_ALERT | ||||||
|  | #define KERN_CRIT | ||||||
|  | #define KERN_ERR | ||||||
|  | #define KERN_WARNING | ||||||
|  | #define KERN_NOTICE | ||||||
|  | #define KERN_INFO | ||||||
|  | #define KERN_DEBUG | ||||||
|  | 
 | ||||||
|  | #define kmalloc(size, flags)	malloc(size) | ||||||
|  | #define kfree(ptr)		free(ptr) | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ..and if you can't take the strict | ||||||
|  |  * types, you can specify one yourself. | ||||||
|  |  * | ||||||
|  |  * Or not use min/max at all, of course. | ||||||
|  |  */ | ||||||
|  | #define min_t(type,x,y) \ | ||||||
|  | 	({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) | ||||||
|  | #define max_t(type,x,y) \ | ||||||
|  | 	({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) | ||||||
|  | 
 | ||||||
|  | #define BUG() do { \ | ||||||
|  | 	printf("U-Boot BUG at %s:%d!\n", __FILE__, __LINE__); \ | ||||||
|  | } while (0) | ||||||
|  | 
 | ||||||
|  | #define BUG_ON(condition) do { if (condition) BUG(); } while(0) | ||||||
|  | 
 | ||||||
|  | #define likely(x)	__builtin_expect(!!(x), 1) | ||||||
|  | #define unlikely(x)	__builtin_expect(!!(x), 0) | ||||||
|  | 
 | ||||||
|  | #define PAGE_SIZE	4096 | ||||||
|  | #endif | ||||||
|  | @ -0,0 +1,99 @@ | ||||||
|  | /*
 | ||||||
|  |  * $Id: mtd-abi.h,v 1.7 2004/11/23 15:37:32 gleixner Exp $ | ||||||
|  |  * | ||||||
|  |  * Portions of MTD ABI definition which are shared by kernel and user space | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __MTD_ABI_H__ | ||||||
|  | #define __MTD_ABI_H__ | ||||||
|  | 
 | ||||||
|  | struct erase_info_user { | ||||||
|  | 	uint32_t start; | ||||||
|  | 	uint32_t length; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct mtd_oob_buf { | ||||||
|  | 	uint32_t start; | ||||||
|  | 	uint32_t length; | ||||||
|  | 	unsigned char *ptr; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #define MTD_ABSENT		0 | ||||||
|  | #define MTD_RAM			1 | ||||||
|  | #define MTD_ROM			2 | ||||||
|  | #define MTD_NORFLASH		3 | ||||||
|  | #define MTD_NANDFLASH		4 | ||||||
|  | #define MTD_PEROM		5 | ||||||
|  | #define MTD_OTHER		14 | ||||||
|  | #define MTD_UNKNOWN		15 | ||||||
|  | 
 | ||||||
|  | #define MTD_CLEAR_BITS		1       /* Bits can be cleared (flash) */ | ||||||
|  | #define MTD_SET_BITS		2       /* Bits can be set */ | ||||||
|  | #define MTD_ERASEABLE		4       /* Has an erase function */ | ||||||
|  | #define MTD_WRITEB_WRITEABLE	8       /* Direct IO is possible */ | ||||||
|  | #define MTD_VOLATILE		16      /* Set for RAMs */ | ||||||
|  | #define MTD_XIP			32	/* eXecute-In-Place possible */ | ||||||
|  | #define MTD_OOB			64	/* Out-of-band data (NAND flash) */ | ||||||
|  | #define MTD_ECC			128	/* Device capable of automatic ECC */ | ||||||
|  | #define MTD_NO_VIRTBLOCKS	256	/* Virtual blocks not allowed */ | ||||||
|  | 
 | ||||||
|  | /* Some common devices / combinations of capabilities */ | ||||||
|  | #define MTD_CAP_ROM		0 | ||||||
|  | #define MTD_CAP_RAM		(MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEB_WRITEABLE) | ||||||
|  | #define MTD_CAP_NORFLASH        (MTD_CLEAR_BITS|MTD_ERASEABLE) | ||||||
|  | #define MTD_CAP_NANDFLASH       (MTD_CLEAR_BITS|MTD_ERASEABLE|MTD_OOB) | ||||||
|  | #define MTD_WRITEABLE		(MTD_CLEAR_BITS|MTD_SET_BITS) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Types of automatic ECC/Checksum available */ | ||||||
|  | #define MTD_ECC_NONE		0 	/* No automatic ECC available */ | ||||||
|  | #define MTD_ECC_RS_DiskOnChip	1	/* Automatic ECC on DiskOnChip */ | ||||||
|  | #define MTD_ECC_SW		2	/* SW ECC for Toshiba & Samsung devices */ | ||||||
|  | 
 | ||||||
|  | /* ECC byte placement */ | ||||||
|  | #define MTD_NANDECC_OFF		0	/* Switch off ECC (Not recommended) */ | ||||||
|  | #define MTD_NANDECC_PLACE	1	/* Use the given placement in the structure (YAFFS1 legacy mode) */ | ||||||
|  | #define MTD_NANDECC_AUTOPLACE	2	/* Use the default placement scheme */ | ||||||
|  | #define MTD_NANDECC_PLACEONLY	3	/* Use the given placement in the structure (Do not store ecc result on read) */ | ||||||
|  | #define MTD_NANDECC_AUTOPL_USR 	4	/* Use the given autoplacement scheme rather than using the default */ | ||||||
|  | 
 | ||||||
|  | struct mtd_info_user { | ||||||
|  | 	uint8_t type; | ||||||
|  | 	uint32_t flags; | ||||||
|  | 	uint32_t size;	 /* Total size of the MTD */ | ||||||
|  | 	uint32_t erasesize; | ||||||
|  | 	uint32_t oobblock;  /* Size of OOB blocks (e.g. 512) */ | ||||||
|  | 	uint32_t oobsize;   /* Amount of OOB data per block (e.g. 16) */ | ||||||
|  | 	uint32_t ecctype; | ||||||
|  | 	uint32_t eccsize; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct region_info_user { | ||||||
|  | 	uint32_t offset;		/* At which this region starts,
 | ||||||
|  | 					 * from the beginning of the MTD */ | ||||||
|  | 	uint32_t erasesize;		/* For this region */ | ||||||
|  | 	uint32_t numblocks;		/* Number of blocks in this region */ | ||||||
|  | 	uint32_t regionindex; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #define MEMGETINFO              _IOR('M', 1, struct mtd_info_user) | ||||||
|  | #define MEMERASE                _IOW('M', 2, struct erase_info_user) | ||||||
|  | #define MEMWRITEOOB             _IOWR('M', 3, struct mtd_oob_buf) | ||||||
|  | #define MEMREADOOB              _IOWR('M', 4, struct mtd_oob_buf) | ||||||
|  | #define MEMLOCK                 _IOW('M', 5, struct erase_info_user) | ||||||
|  | #define MEMUNLOCK               _IOW('M', 6, struct erase_info_user) | ||||||
|  | #define MEMGETREGIONCOUNT	_IOR('M', 7, int) | ||||||
|  | #define MEMGETREGIONINFO	_IOWR('M', 8, struct region_info_user) | ||||||
|  | #define MEMSETOOBSEL		_IOW('M', 9, struct nand_oobinfo) | ||||||
|  | #define MEMGETOOBSEL		_IOR('M', 10, struct nand_oobinfo) | ||||||
|  | #define MEMGETBADBLOCK		_IOW('M', 11, loff_t) | ||||||
|  | #define MEMSETBADBLOCK		_IOW('M', 12, loff_t) | ||||||
|  | 
 | ||||||
|  | struct nand_oobinfo { | ||||||
|  | 	uint32_t useecc; | ||||||
|  | 	uint32_t eccbytes; | ||||||
|  | 	uint32_t oobfree[8][2]; | ||||||
|  | 	uint32_t eccpos[32]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif /* __MTD_ABI_H__ */ | ||||||
|  | @ -0,0 +1,214 @@ | ||||||
|  | /*
 | ||||||
|  |  * $Id: mtd.h,v 1.56 2004/08/09 18:46:04 dmarlin Exp $ | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al. | ||||||
|  |  * | ||||||
|  |  * Released under GPL | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __MTD_MTD_H__ | ||||||
|  | #define __MTD_MTD_H__ | ||||||
|  | #include <linux/types.h> | ||||||
|  | #include <linux/mtd/mtd-abi.h> | ||||||
|  | 
 | ||||||
|  | #define MAX_MTD_DEVICES 16 | ||||||
|  | 
 | ||||||
|  | #define MTD_ERASE_PENDING      	0x01 | ||||||
|  | #define MTD_ERASING		0x02 | ||||||
|  | #define MTD_ERASE_SUSPEND	0x04 | ||||||
|  | #define MTD_ERASE_DONE          0x08 | ||||||
|  | #define MTD_ERASE_FAILED        0x10 | ||||||
|  | 
 | ||||||
|  | /* If the erase fails, fail_addr might indicate exactly which block failed.  If
 | ||||||
|  |    fail_addr = 0xffffffff, the failure was not at the device level or was not | ||||||
|  |    specific to any particular block. */ | ||||||
|  | struct erase_info { | ||||||
|  | 	struct mtd_info *mtd; | ||||||
|  | 	u_int32_t addr; | ||||||
|  | 	u_int32_t len; | ||||||
|  | 	u_int32_t fail_addr; | ||||||
|  | 	u_long time; | ||||||
|  | 	u_long retries; | ||||||
|  | 	u_int dev; | ||||||
|  | 	u_int cell; | ||||||
|  | 	void (*callback) (struct erase_info *self); | ||||||
|  | 	u_long priv; | ||||||
|  | 	u_char state; | ||||||
|  | 	struct erase_info *next; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct mtd_erase_region_info { | ||||||
|  | 	u_int32_t offset;			/* At which this region starts, from the beginning of the MTD */ | ||||||
|  | 	u_int32_t erasesize;		/* For this region */ | ||||||
|  | 	u_int32_t numblocks;		/* Number of blocks of erasesize in this region */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct mtd_info { | ||||||
|  | 	u_char type; | ||||||
|  | 	u_int32_t flags; | ||||||
|  | 	u_int32_t size;	 /* Total size of the MTD */ | ||||||
|  | 
 | ||||||
|  | 	/* "Major" erase size for the device. Naïve users may take this
 | ||||||
|  | 	 * to be the only erase size available, or may use the more detailed | ||||||
|  | 	 * information below if they desire | ||||||
|  | 	 */ | ||||||
|  | 	u_int32_t erasesize; | ||||||
|  | 
 | ||||||
|  | 	u_int32_t oobblock;  /* Size of OOB blocks (e.g. 512) */ | ||||||
|  | 	u_int32_t oobsize;   /* Amount of OOB data per block (e.g. 16) */ | ||||||
|  | 	u_int32_t oobavail;  /* Number of bytes in OOB area available for fs  */ | ||||||
|  | 	u_int32_t ecctype; | ||||||
|  | 	u_int32_t eccsize; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	/* Kernel-only stuff starts here. */ | ||||||
|  | 	char *name; | ||||||
|  | 	int index; | ||||||
|  | 
 | ||||||
|  | 	/* oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO) */ | ||||||
|  | 	struct nand_oobinfo oobinfo; | ||||||
|  | 
 | ||||||
|  | 	/* Data for variable erase regions. If numeraseregions is zero,
 | ||||||
|  | 	 * it means that the whole device has erasesize as given above. | ||||||
|  | 	 */ | ||||||
|  | 	int numeraseregions; | ||||||
|  | 	struct mtd_erase_region_info *eraseregions; | ||||||
|  | 
 | ||||||
|  | 	/* This really shouldn't be here. It can go away in 2.5 */ | ||||||
|  | 	u_int32_t bank_size; | ||||||
|  | 
 | ||||||
|  | 	int (*erase) (struct mtd_info *mtd, struct erase_info *instr); | ||||||
|  | 
 | ||||||
|  | 	/* This stuff for eXecute-In-Place */ | ||||||
|  | 	int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); | ||||||
|  | 
 | ||||||
|  | 	/* We probably shouldn't allow XIP if the unpoint isn't a NULL */ | ||||||
|  | 	void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||||||
|  | 	int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); | ||||||
|  | 
 | ||||||
|  | 	int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); | ||||||
|  | 	int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); | ||||||
|  | 
 | ||||||
|  | 	int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||||||
|  | 	int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * Methods to access the protection register area, present in some | ||||||
|  | 	 * flash devices. The user data is one time programmable but the | ||||||
|  | 	 * factory data is read only. | ||||||
|  | 	 */ | ||||||
|  | 	int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||||||
|  | 
 | ||||||
|  | 	int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||||||
|  | 
 | ||||||
|  | 	/* This function is not yet implemented */ | ||||||
|  | 	int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||||||
|  | #if 0 | ||||||
|  | 	/* kvec-based read/write methods. We need these especially for NAND flash,
 | ||||||
|  | 	   with its limited number of write cycles per erase. | ||||||
|  | 	   NB: The 'count' parameter is the number of _vectors_, each of | ||||||
|  | 	   which contains an (ofs, len) tuple. | ||||||
|  | 	*/ | ||||||
|  | 	int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen); | ||||||
|  | 	int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, | ||||||
|  | 		size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); | ||||||
|  | 	int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); | ||||||
|  | 	int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, | ||||||
|  | 		size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); | ||||||
|  | #endif | ||||||
|  | 	/* Sync */ | ||||||
|  | 	void (*sync) (struct mtd_info *mtd); | ||||||
|  | #if 0 | ||||||
|  | 	/* Chip-supported device locking */ | ||||||
|  | 	int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len); | ||||||
|  | 	int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len); | ||||||
|  | 
 | ||||||
|  | 	/* Power Management functions */ | ||||||
|  | 	int (*suspend) (struct mtd_info *mtd); | ||||||
|  | 	void (*resume) (struct mtd_info *mtd); | ||||||
|  | #endif | ||||||
|  | 	/* Bad block management functions */ | ||||||
|  | 	int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); | ||||||
|  | 	int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); | ||||||
|  | 
 | ||||||
|  | 	void *priv; | ||||||
|  | 
 | ||||||
|  | 	struct module *owner; | ||||||
|  | 	int usecount; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	/* Kernel-side ioctl definitions */ | ||||||
|  | 
 | ||||||
|  | extern int add_mtd_device(struct mtd_info *mtd); | ||||||
|  | extern int del_mtd_device (struct mtd_info *mtd); | ||||||
|  | 
 | ||||||
|  | extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); | ||||||
|  | 
 | ||||||
|  | extern void put_mtd_device(struct mtd_info *mtd); | ||||||
|  | 
 | ||||||
|  | #if 0 | ||||||
|  | struct mtd_notifier { | ||||||
|  | 	void (*add)(struct mtd_info *mtd); | ||||||
|  | 	void (*remove)(struct mtd_info *mtd); | ||||||
|  | 	struct list_head list; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | extern void register_mtd_user (struct mtd_notifier *new); | ||||||
|  | extern int unregister_mtd_user (struct mtd_notifier *old); | ||||||
|  | 
 | ||||||
|  | int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, | ||||||
|  | 		       unsigned long count, loff_t to, size_t *retlen); | ||||||
|  | 
 | ||||||
|  | int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, | ||||||
|  | 		      unsigned long count, loff_t from, size_t *retlen); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args) | ||||||
|  | #define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d)) | ||||||
|  | #define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg) | ||||||
|  | #define MTD_READ(mtd, args...) (*(mtd->read))(mtd, args) | ||||||
|  | #define MTD_WRITE(mtd, args...) (*(mtd->write))(mtd, args) | ||||||
|  | #define MTD_READV(mtd, args...) (*(mtd->readv))(mtd, args) | ||||||
|  | #define MTD_WRITEV(mtd, args...) (*(mtd->writev))(mtd, args) | ||||||
|  | #define MTD_READECC(mtd, args...) (*(mtd->read_ecc))(mtd, args) | ||||||
|  | #define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args) | ||||||
|  | #define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args) | ||||||
|  | #define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args) | ||||||
|  | #define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd);  } while (0) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef CONFIG_MTD_PARTITIONS | ||||||
|  | void mtd_erase_callback(struct erase_info *instr); | ||||||
|  | #else | ||||||
|  | static inline void mtd_erase_callback(struct erase_info *instr) | ||||||
|  | { | ||||||
|  | 	if (instr->callback) | ||||||
|  | 		instr->callback(instr); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Debugging macro and defines | ||||||
|  |  */ | ||||||
|  | #define MTD_DEBUG_LEVEL0	(0)	/* Quiet   */ | ||||||
|  | #define MTD_DEBUG_LEVEL1	(1)	/* Audible */ | ||||||
|  | #define MTD_DEBUG_LEVEL2	(2)	/* Loud    */ | ||||||
|  | #define MTD_DEBUG_LEVEL3	(3)	/* Noisy   */ | ||||||
|  | 
 | ||||||
|  | #ifdef CONFIG_MTD_DEBUG | ||||||
|  | #define DEBUG(n, args...)				\ | ||||||
|  |  	do {						\ | ||||||
|  | 		if (n <= CONFIG_MTD_DEBUG_VERBOSE)	\ | ||||||
|  | 			printk(KERN_INFO args);		\ | ||||||
|  | 	} while(0) | ||||||
|  | #else /* CONFIG_MTD_DEBUG */ | ||||||
|  | #define DEBUG(n, args...) do { } while(0) | ||||||
|  | 
 | ||||||
|  | #endif /* CONFIG_MTD_DEBUG */ | ||||||
|  | 
 | ||||||
|  | #endif /* __MTD_MTD_H__ */ | ||||||
|  | @ -36,6 +36,9 @@ | ||||||
| #ifndef __LINUX_MTD_NAND_H | #ifndef __LINUX_MTD_NAND_H | ||||||
| #define __LINUX_MTD_NAND_H | #define __LINUX_MTD_NAND_H | ||||||
| 
 | 
 | ||||||
|  | #ifdef CONFIG_NEW_NAND_CODE | ||||||
|  | #include "nand_new.h" | ||||||
|  | #else | ||||||
| /*
 | /*
 | ||||||
|  * Standard NAND flash commands |  * Standard NAND flash commands | ||||||
|  */ |  */ | ||||||
|  | @ -196,5 +199,5 @@ struct nand_flash_dev { | ||||||
| #define NAND_JFFS2_OOB16_FSDALEN	8 | #define NAND_JFFS2_OOB16_FSDALEN	8 | ||||||
| 
 | 
 | ||||||
| unsigned long nand_probe(unsigned long physadr); | unsigned long nand_probe(unsigned long physadr); | ||||||
| 
 | #endif /* !CONFIG_NEW_NAND_CODE */ | ||||||
| #endif /* __LINUX_MTD_NAND_H */ | #endif /* __LINUX_MTD_NAND_H */ | ||||||
|  |  | ||||||
|  | @ -0,0 +1,30 @@ | ||||||
|  | /*
 | ||||||
|  |  *  drivers/mtd/nand_ecc.h | ||||||
|  |  * | ||||||
|  |  *  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) | ||||||
|  |  * | ||||||
|  |  * $Id: nand_ecc.h,v 1.4 2004/06/17 02:35:02 dbrown Exp $ | ||||||
|  |  * | ||||||
|  |  * This program is free software; you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License version 2 as | ||||||
|  |  * published by the Free Software Foundation. | ||||||
|  |  * | ||||||
|  |  * This file is the header for the ECC algorithm. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __MTD_NAND_ECC_H__ | ||||||
|  | #define __MTD_NAND_ECC_H__ | ||||||
|  | 
 | ||||||
|  | struct mtd_info; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Calculate 3 byte ECC code for 256 byte block | ||||||
|  |  */ | ||||||
|  | int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Detect and correct a 1 bit error for 256 byte block | ||||||
|  |  */ | ||||||
|  | int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); | ||||||
|  | 
 | ||||||
|  | #endif /* __MTD_NAND_ECC_H__ */ | ||||||
|  | @ -49,6 +49,7 @@ static struct nand_flash_dev nand_flash_ids[] = { | ||||||
| 	{"Samsung KM29W16000",    NAND_MFR_SAMSUNG, 0xea, 21, 1, 2, 0x1000, 0}, | 	{"Samsung KM29W16000",    NAND_MFR_SAMSUNG, 0xea, 21, 1, 2, 0x1000, 0}, | ||||||
| 	{"Samsung K9F5616Q0C",    NAND_MFR_SAMSUNG, 0x45, 25, 0, 2, 0x4000, 1}, | 	{"Samsung K9F5616Q0C",    NAND_MFR_SAMSUNG, 0x45, 25, 0, 2, 0x4000, 1}, | ||||||
| 	{"Samsung K9K1216Q0C",    NAND_MFR_SAMSUNG, 0x46, 26, 0, 3, 0x4000, 1}, | 	{"Samsung K9K1216Q0C",    NAND_MFR_SAMSUNG, 0x46, 26, 0, 3, 0x4000, 1}, | ||||||
|  | 	{"Samsung K9F1G08U0M",    NAND_MFR_SAMSUNG, 0xf1, 27, 0, 2, 0, 0}, | ||||||
| 	{NULL,} | 	{NULL,} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,469 @@ | ||||||
|  | /*
 | ||||||
|  |  *  linux/include/linux/mtd/nand.h | ||||||
|  |  * | ||||||
|  |  *  Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com> | ||||||
|  |  *                     Steven J. Hill <sjhill@realitydiluted.com> | ||||||
|  |  *		       Thomas Gleixner <tglx@linutronix.de> | ||||||
|  |  * | ||||||
|  |  * $Id: nand.h,v 1.68 2004/11/12 10:40:37 gleixner Exp $ | ||||||
|  |  * | ||||||
|  |  * This program is free software; you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License version 2 as | ||||||
|  |  * published by the Free Software Foundation. | ||||||
|  |  * | ||||||
|  |  *  Info: | ||||||
|  |  *   Contains standard defines and IDs for NAND flash devices | ||||||
|  |  * | ||||||
|  |  *  Changelog: | ||||||
|  |  *   01-31-2000 DMW     Created | ||||||
|  |  *   09-18-2000 SJH     Moved structure out of the Disk-On-Chip drivers | ||||||
|  |  *			so it can be used by other NAND flash device | ||||||
|  |  *			drivers. I also changed the copyright since none | ||||||
|  |  *			of the original contents of this file are specific | ||||||
|  |  *			to DoC devices. David can whack me with a baseball | ||||||
|  |  *			bat later if I did something naughty. | ||||||
|  |  *   10-11-2000 SJH     Added private NAND flash structure for driver | ||||||
|  |  *   10-24-2000 SJH     Added prototype for 'nand_scan' function | ||||||
|  |  *   10-29-2001 TG	changed nand_chip structure to support | ||||||
|  |  *			hardwarespecific function for accessing control lines | ||||||
|  |  *   02-21-2002 TG	added support for different read/write adress and | ||||||
|  |  *			ready/busy line access function | ||||||
|  |  *   02-26-2002 TG	added chip_delay to nand_chip structure to optimize | ||||||
|  |  *			command delay times for different chips | ||||||
|  |  *   04-28-2002 TG	OOB config defines moved from nand.c to avoid duplicate | ||||||
|  |  *			defines in jffs2/wbuf.c | ||||||
|  |  *   08-07-2002 TG	forced bad block location to byte 5 of OOB, even if | ||||||
|  |  *			CONFIG_MTD_NAND_ECC_JFFS2 is not set | ||||||
|  |  *   08-10-2002 TG	extensions to nand_chip structure to support HW-ECC | ||||||
|  |  * | ||||||
|  |  *   08-29-2002 tglx 	nand_chip structure: data_poi for selecting | ||||||
|  |  *			internal / fs-driver buffer | ||||||
|  |  *			support for 6byte/512byte hardware ECC | ||||||
|  |  *			read_ecc, write_ecc extended for different oob-layout | ||||||
|  |  *			oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB, | ||||||
|  |  *			NAND_YAFFS_OOB | ||||||
|  |  *  11-25-2002 tglx	Added Manufacturer code FUJITSU, NATIONAL | ||||||
|  |  *			Split manufacturer and device ID structures | ||||||
|  |  * | ||||||
|  |  *  02-08-2004 tglx 	added option field to nand structure for chip anomalities | ||||||
|  |  *  05-25-2004 tglx 	added bad block table support, ST-MICRO manufacturer id | ||||||
|  |  *			update of nand_chip structure description | ||||||
|  |  */ | ||||||
|  | #ifndef __LINUX_MTD_NAND_NEW_H | ||||||
|  | #define __LINUX_MTD_NAND_NEW_H | ||||||
|  | 
 | ||||||
|  | #include <linux/mtd/compat.h> | ||||||
|  | #include <linux/mtd/mtd.h> | ||||||
|  | 
 | ||||||
|  | struct mtd_info; | ||||||
|  | /* Scan and identify a NAND device */ | ||||||
|  | extern int nand_scan (struct mtd_info *mtd, int max_chips); | ||||||
|  | /* Free resources held by the NAND device */ | ||||||
|  | extern void nand_release (struct mtd_info *mtd); | ||||||
|  | 
 | ||||||
|  | /* Read raw data from the device without ECC */ | ||||||
|  | extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* This constant declares the max. oobsize / page, which
 | ||||||
|  |  * is supported now. If you add a chip with bigger oobsize/page | ||||||
|  |  * adjust this accordingly. | ||||||
|  |  */ | ||||||
|  | #define NAND_MAX_OOBSIZE	64 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Constants for hardware specific CLE/ALE/NCE function | ||||||
|  | */ | ||||||
|  | /* Select the chip by setting nCE to low */ | ||||||
|  | #define NAND_CTL_SETNCE 	1 | ||||||
|  | /* Deselect the chip by setting nCE to high */ | ||||||
|  | #define NAND_CTL_CLRNCE		2 | ||||||
|  | /* Select the command latch by setting CLE to high */ | ||||||
|  | #define NAND_CTL_SETCLE		3 | ||||||
|  | /* Deselect the command latch by setting CLE to low */ | ||||||
|  | #define NAND_CTL_CLRCLE		4 | ||||||
|  | /* Select the address latch by setting ALE to high */ | ||||||
|  | #define NAND_CTL_SETALE		5 | ||||||
|  | /* Deselect the address latch by setting ALE to low */ | ||||||
|  | #define NAND_CTL_CLRALE		6 | ||||||
|  | /* Set write protection by setting WP to high. Not used! */ | ||||||
|  | #define NAND_CTL_SETWP		7 | ||||||
|  | /* Clear write protection by setting WP to low. Not used! */ | ||||||
|  | #define NAND_CTL_CLRWP		8 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Standard NAND flash commands | ||||||
|  |  */ | ||||||
|  | #define NAND_CMD_READ0		0 | ||||||
|  | #define NAND_CMD_READ1		1 | ||||||
|  | #define NAND_CMD_PAGEPROG	0x10 | ||||||
|  | #define NAND_CMD_READOOB	0x50 | ||||||
|  | #define NAND_CMD_ERASE1		0x60 | ||||||
|  | #define NAND_CMD_STATUS		0x70 | ||||||
|  | #define NAND_CMD_STATUS_MULTI	0x71 | ||||||
|  | #define NAND_CMD_SEQIN		0x80 | ||||||
|  | #define NAND_CMD_READID		0x90 | ||||||
|  | #define NAND_CMD_ERASE2		0xd0 | ||||||
|  | #define NAND_CMD_RESET		0xff | ||||||
|  | 
 | ||||||
|  | /* Extended commands for large page devices */ | ||||||
|  | #define NAND_CMD_READSTART	0x30 | ||||||
|  | #define NAND_CMD_CACHEDPROG	0x15 | ||||||
|  | 
 | ||||||
|  | /* Status bits */ | ||||||
|  | #define NAND_STATUS_FAIL	0x01 | ||||||
|  | #define NAND_STATUS_FAIL_N1	0x02 | ||||||
|  | #define NAND_STATUS_TRUE_READY	0x20 | ||||||
|  | #define NAND_STATUS_READY	0x40 | ||||||
|  | #define NAND_STATUS_WP		0x80 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Constants for ECC_MODES | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /* No ECC. Usage is not recommended ! */ | ||||||
|  | #define NAND_ECC_NONE		0 | ||||||
|  | /* Software ECC 3 byte ECC per 256 Byte data */ | ||||||
|  | #define NAND_ECC_SOFT		1 | ||||||
|  | /* Hardware ECC 3 byte ECC per 256 Byte data */ | ||||||
|  | #define NAND_ECC_HW3_256	2 | ||||||
|  | /* Hardware ECC 3 byte ECC per 512 Byte data */ | ||||||
|  | #define NAND_ECC_HW3_512	3 | ||||||
|  | /* Hardware ECC 3 byte ECC per 512 Byte data */ | ||||||
|  | #define NAND_ECC_HW6_512	4 | ||||||
|  | /* Hardware ECC 8 byte ECC per 512 Byte data */ | ||||||
|  | #define NAND_ECC_HW8_512	6 | ||||||
|  | /* Hardware ECC 12 byte ECC per 2048 Byte data */ | ||||||
|  | #define NAND_ECC_HW12_2048	7 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Constants for Hardware ECC | ||||||
|  | */ | ||||||
|  | /* Reset Hardware ECC for read */ | ||||||
|  | #define NAND_ECC_READ		0 | ||||||
|  | /* Reset Hardware ECC for write */ | ||||||
|  | #define NAND_ECC_WRITE		1 | ||||||
|  | /* Enable Hardware ECC before syndrom is read back from flash */ | ||||||
|  | #define NAND_ECC_READSYN	2 | ||||||
|  | 
 | ||||||
|  | /* Option constants for bizarre disfunctionality and real
 | ||||||
|  | *  features | ||||||
|  | */ | ||||||
|  | /* Chip can not auto increment pages */ | ||||||
|  | #define NAND_NO_AUTOINCR	0x00000001 | ||||||
|  | /* Buswitdh is 16 bit */ | ||||||
|  | #define NAND_BUSWIDTH_16	0x00000002 | ||||||
|  | /* Device supports partial programming without padding */ | ||||||
|  | #define NAND_NO_PADDING		0x00000004 | ||||||
|  | /* Chip has cache program function */ | ||||||
|  | #define NAND_CACHEPRG		0x00000008 | ||||||
|  | /* Chip has copy back function */ | ||||||
|  | #define NAND_COPYBACK		0x00000010 | ||||||
|  | /* AND Chip which has 4 banks and a confusing page / block
 | ||||||
|  |  * assignment. See Renesas datasheet for further information */ | ||||||
|  | #define NAND_IS_AND		0x00000020 | ||||||
|  | /* Chip has a array of 4 pages which can be read without
 | ||||||
|  |  * additional ready /busy waits */ | ||||||
|  | #define NAND_4PAGE_ARRAY	0x00000040 | ||||||
|  | 
 | ||||||
|  | /* Options valid for Samsung large page devices */ | ||||||
|  | #define NAND_SAMSUNG_LP_OPTIONS \ | ||||||
|  | 	(NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK) | ||||||
|  | 
 | ||||||
|  | /* Macros to identify the above */ | ||||||
|  | #define NAND_CANAUTOINCR(chip) (!(chip->options & NAND_NO_AUTOINCR)) | ||||||
|  | #define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING)) | ||||||
|  | #define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG)) | ||||||
|  | #define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK)) | ||||||
|  | 
 | ||||||
|  | /* Mask to zero out the chip options, which come from the id table */ | ||||||
|  | #define NAND_CHIPOPTIONS_MSK	(0x0000ffff & ~NAND_NO_AUTOINCR) | ||||||
|  | 
 | ||||||
|  | /* Non chip related options */ | ||||||
|  | /* Use a flash based bad block table. This option is passed to the
 | ||||||
|  |  * default bad block table function. */ | ||||||
|  | #define NAND_USE_FLASH_BBT	0x00010000 | ||||||
|  | /* The hw ecc generator provides a syndrome instead a ecc value on read
 | ||||||
|  |  * This can only work if we have the ecc bytes directly behind the | ||||||
|  |  * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */ | ||||||
|  | #define NAND_HWECC_SYNDROME	0x00020000 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Options set by nand scan */ | ||||||
|  | /* Nand scan has allocated oob_buf */ | ||||||
|  | #define NAND_OOBBUF_ALLOC	0x40000000 | ||||||
|  | /* Nand scan has allocated data_buf */ | ||||||
|  | #define NAND_DATABUF_ALLOC	0x80000000 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * nand_state_t - chip states | ||||||
|  |  * Enumeration for NAND flash chip state | ||||||
|  |  */ | ||||||
|  | typedef enum { | ||||||
|  | 	FL_READY, | ||||||
|  | 	FL_READING, | ||||||
|  | 	FL_WRITING, | ||||||
|  | 	FL_ERASING, | ||||||
|  | 	FL_SYNCING, | ||||||
|  | 	FL_CACHEDPRG, | ||||||
|  | } nand_state_t; | ||||||
|  | 
 | ||||||
|  | /* Keep gcc happy */ | ||||||
|  | struct nand_chip; | ||||||
|  | 
 | ||||||
|  | #if 0 | ||||||
|  | /**
 | ||||||
|  |  * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices | ||||||
|  |  * @lock:               protection lock | ||||||
|  |  * @active:		the mtd device which holds the controller currently | ||||||
|  |  */ | ||||||
|  | struct nand_hw_control { | ||||||
|  | 	spinlock_t	 lock; | ||||||
|  | 	struct nand_chip *active; | ||||||
|  | }; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * struct nand_chip - NAND Private Flash Chip Data | ||||||
|  |  * @IO_ADDR_R:		[BOARDSPECIFIC] address to read the 8 I/O lines of the flash device | ||||||
|  |  * @IO_ADDR_W:		[BOARDSPECIFIC] address to write the 8 I/O lines of the flash device | ||||||
|  |  * @read_byte:		[REPLACEABLE] read one byte from the chip | ||||||
|  |  * @write_byte:		[REPLACEABLE] write one byte to the chip | ||||||
|  |  * @read_word:		[REPLACEABLE] read one word from the chip | ||||||
|  |  * @write_word:		[REPLACEABLE] write one word to the chip | ||||||
|  |  * @write_buf:		[REPLACEABLE] write data from the buffer to the chip | ||||||
|  |  * @read_buf:		[REPLACEABLE] read data from the chip into the buffer | ||||||
|  |  * @verify_buf:		[REPLACEABLE] verify buffer contents against the chip data | ||||||
|  |  * @select_chip:	[REPLACEABLE] select chip nr | ||||||
|  |  * @block_bad:		[REPLACEABLE] check, if the block is bad | ||||||
|  |  * @block_markbad:	[REPLACEABLE] mark the block bad | ||||||
|  |  * @hwcontrol:		[BOARDSPECIFIC] hardwarespecific function for accesing control-lines | ||||||
|  |  * @dev_ready:		[BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line | ||||||
|  |  *			If set to NULL no access to ready/busy is available and the ready/busy information | ||||||
|  |  *			is read from the chip status register | ||||||
|  |  * @cmdfunc:		[REPLACEABLE] hardwarespecific function for writing commands to the chip | ||||||
|  |  * @waitfunc:		[REPLACEABLE] hardwarespecific function for wait on ready | ||||||
|  |  * @calculate_ecc: 	[REPLACEABLE] function for ecc calculation or readback from ecc hardware | ||||||
|  |  * @correct_data:	[REPLACEABLE] function for ecc correction, matching to ecc generator (sw/hw) | ||||||
|  |  * @enable_hwecc:	[BOARDSPECIFIC] function to enable (reset) hardware ecc generator. Must only | ||||||
|  |  *			be provided if a hardware ECC is available | ||||||
|  |  * @erase_cmd:		[INTERN] erase command write function, selectable due to AND support | ||||||
|  |  * @scan_bbt:		[REPLACEABLE] function to scan bad block table | ||||||
|  |  * @eccmode:		[BOARDSPECIFIC] mode of ecc, see defines | ||||||
|  |  * @eccsize: 		[INTERN] databytes used per ecc-calculation | ||||||
|  |  * @eccbytes: 		[INTERN] number of ecc bytes per ecc-calculation step | ||||||
|  |  * @eccsteps:		[INTERN] number of ecc calculation steps per page | ||||||
|  |  * @chip_delay:		[BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR) | ||||||
|  |  * @chip_lock:		[INTERN] spinlock used to protect access to this structure and the chip | ||||||
|  |  * @wq:			[INTERN] wait queue to sleep on if a NAND operation is in progress | ||||||
|  |  * @state: 		[INTERN] the current state of the NAND device | ||||||
|  |  * @page_shift:		[INTERN] number of address bits in a page (column address bits) | ||||||
|  |  * @phys_erase_shift:	[INTERN] number of address bits in a physical eraseblock | ||||||
|  |  * @bbt_erase_shift:	[INTERN] number of address bits in a bbt entry | ||||||
|  |  * @chip_shift:		[INTERN] number of address bits in one chip | ||||||
|  |  * @data_buf:		[INTERN] internal buffer for one page + oob | ||||||
|  |  * @oob_buf:		[INTERN] oob buffer for one eraseblock | ||||||
|  |  * @oobdirty:		[INTERN] indicates that oob_buf must be reinitialized | ||||||
|  |  * @data_poi:		[INTERN] pointer to a data buffer | ||||||
|  |  * @options:		[BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about | ||||||
|  |  *			special functionality. See the defines for further explanation | ||||||
|  |  * @badblockpos:	[INTERN] position of the bad block marker in the oob area | ||||||
|  |  * @numchips:		[INTERN] number of physical chips | ||||||
|  |  * @chipsize:		[INTERN] the size of one chip for multichip arrays | ||||||
|  |  * @pagemask:		[INTERN] page number mask = number of (pages / chip) - 1 | ||||||
|  |  * @pagebuf:		[INTERN] holds the pagenumber which is currently in data_buf | ||||||
|  |  * @autooob:		[REPLACEABLE] the default (auto)placement scheme | ||||||
|  |  * @bbt:		[INTERN] bad block table pointer | ||||||
|  |  * @bbt_td:		[REPLACEABLE] bad block table descriptor for flash lookup | ||||||
|  |  * @bbt_md:		[REPLACEABLE] bad block table mirror descriptor | ||||||
|  |  * @badblock_pattern:	[REPLACEABLE] bad block scan pattern used for initial bad block scan | ||||||
|  |  * @controller:		[OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices | ||||||
|  |  * @priv:		[OPTIONAL] pointer to private chip date | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | struct nand_chip { | ||||||
|  | 	void  __iomem	*IO_ADDR_R; | ||||||
|  | 	void  __iomem 	*IO_ADDR_W; | ||||||
|  | 
 | ||||||
|  | 	u_char		(*read_byte)(struct mtd_info *mtd); | ||||||
|  | 	void		(*write_byte)(struct mtd_info *mtd, u_char byte); | ||||||
|  | 	u16		(*read_word)(struct mtd_info *mtd); | ||||||
|  | 	void		(*write_word)(struct mtd_info *mtd, u16 word); | ||||||
|  | 
 | ||||||
|  | 	void		(*write_buf)(struct mtd_info *mtd, const u_char *buf, int len); | ||||||
|  | 	void		(*read_buf)(struct mtd_info *mtd, u_char *buf, int len); | ||||||
|  | 	int		(*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len); | ||||||
|  | 	void		(*select_chip)(struct mtd_info *mtd, int chip); | ||||||
|  | 	int		(*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip); | ||||||
|  | 	int		(*block_markbad)(struct mtd_info *mtd, loff_t ofs); | ||||||
|  | 	void 		(*hwcontrol)(struct mtd_info *mtd, int cmd); | ||||||
|  | 	int  		(*dev_ready)(struct mtd_info *mtd); | ||||||
|  | 	void 		(*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); | ||||||
|  | 	int 		(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); | ||||||
|  | 	int		(*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); | ||||||
|  | 	int 		(*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); | ||||||
|  | 	void		(*enable_hwecc)(struct mtd_info *mtd, int mode); | ||||||
|  | 	void		(*erase_cmd)(struct mtd_info *mtd, int page); | ||||||
|  | 	int		(*scan_bbt)(struct mtd_info *mtd); | ||||||
|  | 	int		eccmode; | ||||||
|  | 	int		eccsize; | ||||||
|  | 	int		eccbytes; | ||||||
|  | 	int		eccsteps; | ||||||
|  | 	int 		chip_delay; | ||||||
|  | #if 0 | ||||||
|  | 	spinlock_t	chip_lock; | ||||||
|  | 	wait_queue_head_t wq; | ||||||
|  | 	nand_state_t 	state; | ||||||
|  | #endif | ||||||
|  | 	int 		page_shift; | ||||||
|  | 	int		phys_erase_shift; | ||||||
|  | 	int		bbt_erase_shift; | ||||||
|  | 	int		chip_shift; | ||||||
|  | 	u_char 		*data_buf; | ||||||
|  | 	u_char		*oob_buf; | ||||||
|  | 	int		oobdirty; | ||||||
|  | 	u_char		*data_poi; | ||||||
|  | 	unsigned int	options; | ||||||
|  | 	int		badblockpos; | ||||||
|  | 	int		numchips; | ||||||
|  | 	unsigned long	chipsize; | ||||||
|  | 	int		pagemask; | ||||||
|  | 	int		pagebuf; | ||||||
|  | 	struct nand_oobinfo	*autooob; | ||||||
|  | 	uint8_t		*bbt; | ||||||
|  | 	struct nand_bbt_descr	*bbt_td; | ||||||
|  | 	struct nand_bbt_descr	*bbt_md; | ||||||
|  | 	struct nand_bbt_descr	*badblock_pattern; | ||||||
|  | 	struct nand_hw_control  *controller; | ||||||
|  | 	void		*priv; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * NAND Flash Manufacturer ID Codes | ||||||
|  |  */ | ||||||
|  | #define NAND_MFR_TOSHIBA	0x98 | ||||||
|  | #define NAND_MFR_SAMSUNG	0xec | ||||||
|  | #define NAND_MFR_FUJITSU	0x04 | ||||||
|  | #define NAND_MFR_NATIONAL	0x8f | ||||||
|  | #define NAND_MFR_RENESAS	0x07 | ||||||
|  | #define NAND_MFR_STMICRO	0x20 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * struct nand_flash_dev - NAND Flash Device ID Structure | ||||||
|  |  * | ||||||
|  |  * @name:  	Identify the device type | ||||||
|  |  * @id:   	device ID code | ||||||
|  |  * @pagesize:  	Pagesize in bytes. Either 256 or 512 or 0 | ||||||
|  |  *		If the pagesize is 0, then the real pagesize | ||||||
|  |  *		and the eraseize are determined from the | ||||||
|  |  *		extended id bytes in the chip | ||||||
|  |  * @erasesize: 	Size of an erase block in the flash device. | ||||||
|  |  * @chipsize:  	Total chipsize in Mega Bytes | ||||||
|  |  * @options:	Bitfield to store chip relevant options | ||||||
|  |  */ | ||||||
|  | struct nand_flash_dev { | ||||||
|  | 	char *name; | ||||||
|  | 	int id; | ||||||
|  | 	unsigned long pagesize; | ||||||
|  | 	unsigned long chipsize; | ||||||
|  | 	unsigned long erasesize; | ||||||
|  | 	unsigned long options; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * struct nand_manufacturers - NAND Flash Manufacturer ID Structure | ||||||
|  |  * @name:	Manufacturer name | ||||||
|  |  * @id: 	manufacturer ID code of device. | ||||||
|  | */ | ||||||
|  | struct nand_manufacturers { | ||||||
|  | 	int id; | ||||||
|  | 	char * name; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | extern struct nand_flash_dev nand_flash_ids[]; | ||||||
|  | extern struct nand_manufacturers nand_manuf_ids[]; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * struct nand_bbt_descr - bad block table descriptor | ||||||
|  |  * @options:	options for this descriptor | ||||||
|  |  * @pages:	the page(s) where we find the bbt, used with option BBT_ABSPAGE | ||||||
|  |  *		when bbt is searched, then we store the found bbts pages here. | ||||||
|  |  *		Its an array and supports up to 8 chips now | ||||||
|  |  * @offs:	offset of the pattern in the oob area of the page | ||||||
|  |  * @veroffs:	offset of the bbt version counter in the oob are of the page | ||||||
|  |  * @version:	version read from the bbt page during scan | ||||||
|  |  * @len:	length of the pattern, if 0 no pattern check is performed | ||||||
|  |  * @maxblocks:	maximum number of blocks to search for a bbt. This number of | ||||||
|  |  *		blocks is reserved at the end of the device where the tables are | ||||||
|  |  *		written. | ||||||
|  |  * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than | ||||||
|  |  *              bad) block in the stored bbt | ||||||
|  |  * @pattern:	pattern to identify bad block table or factory marked good / | ||||||
|  |  *		bad blocks, can be NULL, if len = 0 | ||||||
|  |  * | ||||||
|  |  * Descriptor for the bad block table marker and the descriptor for the | ||||||
|  |  * pattern which identifies good and bad blocks. The assumption is made | ||||||
|  |  * that the pattern and the version count are always located in the oob area | ||||||
|  |  * of the first block. | ||||||
|  |  */ | ||||||
|  | struct nand_bbt_descr { | ||||||
|  | 	int	options; | ||||||
|  | 	int	pages[NAND_MAX_CHIPS]; | ||||||
|  | 	int	offs; | ||||||
|  | 	int	veroffs; | ||||||
|  | 	uint8_t	version[NAND_MAX_CHIPS]; | ||||||
|  | 	int	len; | ||||||
|  | 	int 	maxblocks; | ||||||
|  | 	int	reserved_block_code; | ||||||
|  | 	uint8_t	*pattern; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* Options for the bad block table descriptors */ | ||||||
|  | 
 | ||||||
|  | /* The number of bits used per block in the bbt on the device */ | ||||||
|  | #define NAND_BBT_NRBITS_MSK	0x0000000F | ||||||
|  | #define NAND_BBT_1BIT		0x00000001 | ||||||
|  | #define NAND_BBT_2BIT		0x00000002 | ||||||
|  | #define NAND_BBT_4BIT		0x00000004 | ||||||
|  | #define NAND_BBT_8BIT		0x00000008 | ||||||
|  | /* The bad block table is in the last good block of the device */ | ||||||
|  | #define	NAND_BBT_LASTBLOCK	0x00000010 | ||||||
|  | /* The bbt is at the given page, else we must scan for the bbt */ | ||||||
|  | #define NAND_BBT_ABSPAGE	0x00000020 | ||||||
|  | /* The bbt is at the given page, else we must scan for the bbt */ | ||||||
|  | #define NAND_BBT_SEARCH		0x00000040 | ||||||
|  | /* bbt is stored per chip on multichip devices */ | ||||||
|  | #define NAND_BBT_PERCHIP	0x00000080 | ||||||
|  | /* bbt has a version counter at offset veroffs */ | ||||||
|  | #define NAND_BBT_VERSION	0x00000100 | ||||||
|  | /* Create a bbt if none axists */ | ||||||
|  | #define NAND_BBT_CREATE		0x00000200 | ||||||
|  | /* Search good / bad pattern through all pages of a block */ | ||||||
|  | #define NAND_BBT_SCANALLPAGES	0x00000400 | ||||||
|  | /* Scan block empty during good / bad block scan */ | ||||||
|  | #define NAND_BBT_SCANEMPTY	0x00000800 | ||||||
|  | /* Write bbt if neccecary */ | ||||||
|  | #define NAND_BBT_WRITE		0x00001000 | ||||||
|  | /* Read and write back block contents when writing bbt */ | ||||||
|  | #define NAND_BBT_SAVECONTENT	0x00002000 | ||||||
|  | /* Search good / bad pattern on the first and the second page */ | ||||||
|  | #define NAND_BBT_SCAN2NDPAGE	0x00004000 | ||||||
|  | 
 | ||||||
|  | /* The maximum number of blocks to scan for a bbt */ | ||||||
|  | #define NAND_BBT_SCAN_MAXBLOCKS	4 | ||||||
|  | 
 | ||||||
|  | extern int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd); | ||||||
|  | extern int nand_update_bbt (struct mtd_info *mtd, loff_t offs); | ||||||
|  | extern int nand_default_bbt (struct mtd_info *mtd); | ||||||
|  | extern int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt); | ||||||
|  | extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | * Constants for oob configuration | ||||||
|  | */ | ||||||
|  | #define NAND_SMALL_BADBLOCK_POS		5 | ||||||
|  | #define NAND_LARGE_BADBLOCK_POS		0 | ||||||
|  | 
 | ||||||
|  | #endif /* __LINUX_MTD_NAND_NEW_H */ | ||||||
|  | @ -0,0 +1,63 @@ | ||||||
|  | /*
 | ||||||
|  |  * (C) Copyright 2005 | ||||||
|  |  * 2N Telekomunikace, a.s. <www.2n.cz> | ||||||
|  |  * Ladislav Michl <michl@2n.cz> | ||||||
|  |  * | ||||||
|  |  * 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 | ||||||
|  |  * version 2 as published by the Free Software Foundation. | ||||||
|  |  * | ||||||
|  |  * 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 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef _NAND_H_ | ||||||
|  | #define _NAND_H_ | ||||||
|  | 
 | ||||||
|  | #include <linux/mtd/compat.h> | ||||||
|  | #include <linux/mtd/mtd.h> | ||||||
|  | #include <linux/mtd/nand.h> | ||||||
|  | 
 | ||||||
|  | typedef struct mtd_info nand_info_t; | ||||||
|  | 
 | ||||||
|  | extern int nand_curr_device; | ||||||
|  | extern nand_info_t nand_info[]; | ||||||
|  | 
 | ||||||
|  | static inline int nand_read(nand_info_t *info, ulong ofs, ulong *len, u_char *buf) | ||||||
|  | { | ||||||
|  | 	return info->read(info, ofs, *len, (size_t *)len, buf); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline int nand_write(nand_info_t *info, ulong ofs, ulong *len, u_char *buf) | ||||||
|  | { | ||||||
|  | 	return info->write(info, ofs, *len, (size_t *)len, buf); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline int nand_block_isbad(nand_info_t *info, ulong ofs) | ||||||
|  | { | ||||||
|  | 	return info->block_isbad(info, ofs); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline int nand_erase(nand_info_t *info, ulong off, ulong size) | ||||||
|  | { | ||||||
|  | 	struct erase_info instr; | ||||||
|  | 
 | ||||||
|  | 	instr.mtd = info; | ||||||
|  | 	instr.addr = off; | ||||||
|  | 	instr.len = size; | ||||||
|  | 	instr.callback = 0; | ||||||
|  | 
 | ||||||
|  | 	return info->erase(info, &instr); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
		Loading…
	
		Reference in New Issue