Update of new NAND code

Patch by Ladislav Michl, 13 Sep 2005
master
Wolfgang Denk 20 years ago
parent 05b47540aa
commit ac7eb8a315
  1. 12
      Makefile
  2. 85
      board/netstar/Makefile
  3. 11
      board/netstar/config.mk
  4. 177
      board/netstar/crcek.S
  5. 3
      board/netstar/crcek.h
  6. 86
      board/netstar/crcit.c
  7. 215
      board/netstar/eeprom.c
  8. 51
      board/netstar/eeprom.lds
  9. 177
      board/netstar/eeprom_start.S
  10. 343
      board/netstar/flash.c
  11. 64
      board/netstar/nand.c
  12. 68
      board/netstar/netstar.c
  13. 287
      board/netstar/setup.S
  14. 55
      board/netstar/u-boot.lds
  15. 19
      common/cmd_jffs2.c
  16. 2040
      common/cmd_nand.c
  17. 364
      common/cmd_nand_new.c
  18. 2
      cpu/arm925t/config.mk
  19. 1
      drivers/nand/Makefile
  20. 198
      drivers/nand/diskonchip.c
  21. 494
      drivers/nand/nand_base.c
  22. 242
      drivers/nand/nand_bbt.c
  23. 45
      drivers/nand/nand_ecc.c
  24. 28
      drivers/nand/nand_ids.c
  25. 8
      fs/jffs2/jffs2_1pass.c
  26. 39
      fs/jffs2/jffs2_nand_1pass.c
  27. 8
      include/asm-arm/io.h
  28. 265
      include/configs/netstar.h
  29. 48
      include/linux/mtd/mtd-abi.h
  30. 34
      include/linux/mtd/mtd.h
  31. 44
      include/linux/mtd/nand.h
  32. 2
      include/nand.h

@ -118,6 +118,7 @@ LIBS += disk/libdisk.a
LIBS += rtc/librtc.a
LIBS += dtt/libdtt.a
LIBS += drivers/libdrivers.a
LIBS += drivers/nand/libnand.a
LIBS += drivers/sk98lin/libsk98lin.a
LIBS += post/libpost.a post/cpu/libcpu.a
LIBS += common/libcommon.a
@ -1391,6 +1392,17 @@ mx1ads_config : unconfig
mx1fs2_config : unconfig
@./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
@./mkconfig $(@:_config=) arm arm925t omap1510inn

@ -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,11 @@
#
# 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

@ -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)

@ -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;
}

@ -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 = .;
}

@ -99,6 +99,10 @@
#include <cramfs/cramfs_fs.h>
#ifdef CONFIG_NEW_NAND_CODE
#include <nand.h>
#endif
/* enable/disable debugging messages */
#define DEBUG
#undef DEBUG
@ -324,10 +328,9 @@ static int part_validate_nand(struct mtdids *id, struct part_info *part)
{
#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND)
/* info for NAND chips */
extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
struct nand_chip *nand;
nand_info_t *nand;
nand = &nand_dev_desc[id->num];
nand = &nand_info[id->num];
if ((unsigned long)(part->offset) % nand->erasesize) {
printf("%s%d: partition (%s) start offset alignment incorrect\n",
@ -422,8 +425,9 @@ static int part_del(struct mtd_device *dev, struct part_info *part)
}
}
#ifndef CONFIG_NEW_NAND_CODE
jffs2_free_cache(part);
#endif
list_del(&part->link);
free(part);
dev->num_parts--;
@ -445,7 +449,9 @@ static void part_delall(struct list_head *head)
list_for_each_safe(entry, n, head) {
part_tmp = list_entry(entry, struct part_info, link);
#ifndef CONFIG_NEW_NAND_CODE
jffs2_free_cache(part_tmp);
#endif
list_del(entry);
free(part_tmp);
}
@ -661,6 +667,7 @@ static int device_validate(u8 type, u8 num, u32 *size)
if (num < CFG_MAX_FLASH_BANKS) {
extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
*size = flash_info[num].size;
return 0;
}
@ -672,8 +679,12 @@ static int device_validate(u8 type, u8 num, u32 *size)
} else if (type == MTD_DEV_TYPE_NAND) {
#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND)
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];
*size = nand_dev_desc[num].totlen;
#endif
return 0;
}

File diff suppressed because it is too large Load Diff

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

@ -22,6 +22,6 @@
#
PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
-mshort-load-bytes -msoft-float
-msoft-float
PLATFORM_CPPFLAGS += -mapcs-32 -march=armv4

@ -14,4 +14,3 @@ $(LIB): $(OBJS)
$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
sinclude .depend

@ -1,4 +1,4 @@
/*
/*
* drivers/mtd/nand/diskonchip.c
*
* (C) 2003 Red Hat, Inc.
@ -8,12 +8,12 @@
* Author: David Woodhouse <dwmw2@infradead.org>
* Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org>
* Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee>
*
*
* Error correction code lifted from the old docecc code
* Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Copyright (C) 2000 Netgem S.A.
* converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de>
*
*
* Interface to generic NAND code for M-Systems DiskOnChip devices
*
* $Id: diskonchip.c,v 1.45 2005/01/05 18:05:14 dwmw2 Exp $
@ -42,25 +42,25 @@
static unsigned long __initdata doc_locations[] = {
#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_MTD_DISKONCHIP_PROBE_HIGH
0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
#else /* CONFIG_MTD_DOCPROBE_HIGH */
0xc8000, 0xca000, 0xcc000, 0xce000,
0xc8000, 0xca000, 0xcc000, 0xce000,
0xd0000, 0xd2000, 0xd4000, 0xd6000,
0xd8000, 0xda000, 0xdc000, 0xde000,
0xe0000, 0xe2000, 0xe4000, 0xe6000,
0xd8000, 0xda000, 0xdc000, 0xde000,
0xe0000, 0xe2000, 0xe4000, 0xe6000,
0xe8000, 0xea000, 0xec000, 0xee000,
#endif /* CONFIG_MTD_DOCPROBE_HIGH */
#elif defined(__PPC__)
0xe4000000,
#elif defined(CONFIG_MOMENCO_OCELOT)
0x2f000000,
0xff000000,
0xff000000,
#elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)
0xff000000,
0xff000000,
##else
#warning Unknown architecture for DiskOnChip. No default probe locations defined
#endif
@ -142,7 +142,7 @@ MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe
/* the Reed Solomon control structure */
static struct rs_control *rs_decoder;
/*
/*
* The HW decoder in the DoC ASIC's provides us a error syndrome,
* which we must convert to a standard syndrom usable by the generic
* Reed-Solomon library code.
@ -167,8 +167,8 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
/* Initialize the syndrom buffer */
for (i = 0; i < NROOTS; i++)
s[i] = ds[0];
/*
* Evaluate
/*
* Evaluate
* s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0]
* where x = alpha^(FCR + i)
*/
@ -192,7 +192,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
if (nerr < 0)
return nerr;
/*
/*
* Correct the errors. The bitpositions are a bit of magic,
* but they are given by the design of the de/encoder circuit
* in the DoC ASIC's.
@ -209,7 +209,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
can be modified since pos is even */
index = (pos >> 3) ^ 1;
bitpos = pos & 7;
if ((index >= 0 && index < SECTOR_SIZE) ||
if ((index >= 0 && index < SECTOR_SIZE) ||
index == (SECTOR_SIZE + 1)) {
val = (uint8_t) (errval[i] >> (2 + bitpos));
parity ^= val;
@ -220,7 +220,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
bitpos = (bitpos + 10) & 7;
if (bitpos == 0)
bitpos = 8;
if ((index >= 0 && index < SECTOR_SIZE) ||
if ((index >= 0 && index < SECTOR_SIZE) ||
index == (SECTOR_SIZE + 1)) {
val = (uint8_t)(errval[i] << (8 - bitpos));
parity ^= val;
@ -237,7 +237,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
{
volatile char dummy;
int i;
for (i = 0; i < cycles; i++) {
if (DoC_is_Millennium(doc))
dummy = ReadDOC(doc->virtadr, NOP);
@ -246,7 +246,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
else
dummy = ReadDOC(doc->virtadr, DOCStatus);
}
}
#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
@ -254,7 +254,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
static int _DoC_WaitReady(struct doc_priv *doc)
{
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
unsigned long timeo = jiffies + (HZ * 10);
if(debug) printk("_DoC_WaitReady...\n");
@ -284,7 +284,7 @@ static int _DoC_WaitReady(struct doc_priv *doc)
static inline int DoC_WaitReady(struct doc_priv *doc)
{
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
int ret = 0;
if (DoC_is_MillenniumPlus(doc)) {
@ -310,7 +310,7 @@ static void doc2000_write_byte(struct mtd_info *mtd, u_char datum)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
if(debug)printk("write_byte %02x\n", datum);
WriteDOC(datum, docptr, CDSNSlowIO);
@ -321,7 +321,7 @@ static u_char doc2000_read_byte(struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
u_char ret;
ReadDOC(docptr, CDSNSlowIO);
@ -331,12 +331,12 @@ static u_char doc2000_read_byte(struct mtd_info *mtd)
return ret;
}
static void doc2000_writebuf(struct mtd_info *mtd,
static void doc2000_writebuf(struct mtd_info *mtd,
const u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
int i;
if (debug)printk("writebuf of %d bytes: ", len);
for (i=0; i < len; i++) {
@ -347,12 +347,12 @@ static void doc2000_writebuf(struct mtd_info *mtd,
if (debug) printk("\n");
}
static void doc2000_readbuf(struct mtd_info *mtd,
static void doc2000_readbuf(struct mtd_info *mtd,
u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
int i;
if (debug)printk("readbuf of %d bytes: ", len);
@ -362,12 +362,12 @@ static void doc2000_readbuf(struct mtd_info *mtd,
}
}
static void doc2000_readbuf_dword(struct mtd_info *mtd,
static void doc2000_readbuf_dword(struct mtd_info *mtd,
u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
int i;
if (debug) printk("readbuf_dword of %d bytes: ", len);
@ -383,12 +383,12 @@ static void doc2000_readbuf_dword(struct mtd_info *mtd,
}
}
static int doc2000_verifybuf(struct mtd_info *mtd,
static int doc2000_verifybuf(struct mtd_info *mtd,
const u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
int i;
for (i=0; i < len; i++)
@ -435,7 +435,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
this->read_buf = &doc2000_readbuf_dword;
}
}
return ret;
}
@ -466,7 +466,7 @@ static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
struct doc_priv *doc = this->priv;
int status;
DoC_WaitReady(doc);
this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
DoC_WaitReady(doc);
@ -479,7 +479,7 @@ static void doc2001_write_byte(struct mtd_info *mtd, u_char datum)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
WriteDOC(datum, docptr, CDSNSlowIO);
WriteDOC(datum, docptr, Mil_CDSN_IO);
@ -490,22 +490,22 @@ static u_char doc2001_read_byte(struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
//ReadDOC(docptr, CDSNSlowIO);
/*ReadDOC(docptr, CDSNSlowIO); */
/* 11.4.5 -- delay twice to allow extended length cycle */
DoC_Delay(doc, 2);
ReadDOC(docptr, ReadPipeInit);
//return ReadDOC(docptr, Mil_CDSN_IO);
/*return ReadDOC(docptr, Mil_CDSN_IO); */
return ReadDOC(docptr, LastDataRead);
}
static void doc2001_writebuf(struct mtd_info *mtd,
static void doc2001_writebuf(struct mtd_info *mtd,
const u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
int i;
for (i=0; i < len; i++)
@ -514,12 +514,12 @@ static void doc2001_writebuf(struct mtd_info *mtd,
WriteDOC(0x00, docptr, WritePipeTerm);
}
static void doc2001_readbuf(struct mtd_info *mtd,
static void doc2001_readbuf(struct mtd_info *mtd,
u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
int i;
/* Start read pipeline */
@ -532,12 +532,12 @@ static void doc2001_readbuf(struct mtd_info *mtd,
buf[i] = ReadDOC(docptr, LastDataRead);
}
static int doc2001_verifybuf(struct mtd_info *mtd,
static int doc2001_verifybuf(struct mtd_info *mtd,
const u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
int i;
/* Start read pipeline */
@ -557,22 +557,22 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
u_char ret;
ReadDOC(docptr, Mplus_ReadPipeInit);
ReadDOC(docptr, Mplus_ReadPipeInit);
ret = ReadDOC(docptr, Mplus_LastDataRead);
ReadDOC(docptr, Mplus_ReadPipeInit);
ReadDOC(docptr, Mplus_ReadPipeInit);
ret = ReadDOC(docptr, Mplus_LastDataRead);
if (debug) printk("read_byte returns %02x\n", ret);
return ret;
}
static void doc2001plus_writebuf(struct mtd_info *mtd,
static void doc2001plus_writebuf(struct mtd_info *mtd,
const u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
int i;
if (debug)printk("writebuf of %d bytes: ", len);
@ -584,12 +584,12 @@ static void doc2001plus_writebuf(struct mtd_info *mtd,
if (debug) printk("\n");
}
static void doc2001plus_readbuf(struct mtd_info *mtd,
static void doc2001plus_readbuf(struct mtd_info *mtd,
u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
int i;
if (debug)printk("readbuf of %d bytes: ", len);
@ -614,12 +614,12 @@ static void doc2001plus_readbuf(struct mtd_info *mtd,
if (debug) printk("\n");
}
static int doc2001plus_verifybuf(struct mtd_info *mtd,
static int doc2001plus_verifybuf(struct mtd_info *mtd,
const u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
int i;
if (debug)printk("verifybuf of %d bytes: ", len);
@ -645,7 +645,7 @@ static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
int floor = 0;
if(debug)printk("select chip (%d)\n", chip);
@ -671,7 +671,7 @@ static void doc200x_select_chip(struct mtd_info *mtd, int chip)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
int floor = 0;
if(debug)printk("select chip (%d)\n", chip);
@ -698,7 +698,7 @@ static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
switch(cmd) {
case NAND_CTL_SETNCE:
@ -736,7 +736,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
/*
* Must terminate write pipeline before sending any commands
@ -794,7 +794,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
WriteDOC(0, docptr, Mplus_FlashControl);
}
/*
/*
* program and erase have their own busy handlers
* status and sequential in needs no delay
*/
@ -819,7 +819,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
/* This applies to read commands */
default:
/*
/*
* If we don't have access to the busy pin, we apply the given
* command delay
*/
@ -840,7 +840,7 @@ static int doc200x_dev_ready(struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
if (DoC_is_MillenniumPlus(doc)) {
/* 11.4.2 -- must NOP four times before checking FR/B# */
@ -878,7 +878,7 @@ static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
/* Prime the ECC engine */
switch(mode) {
@ -897,7 +897,7 @@ static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
/* Prime the ECC engine */
switch(mode) {
@ -918,7 +918,7 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
int i;
int emptymatch = 1;
@ -942,7 +942,7 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
for (i = 0; i < 6; i++) {
if (DoC_is_MillenniumPlus(doc))
ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);
else
else
ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
if (ecc_code[i] != empty_write_ecc[i])
emptymatch = 0;
@ -976,10 +976,10 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
int i, ret = 0;
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
void __iomem *docptr = doc->virtadr;
void __iomem *docptr = doc->virtadr;
volatile u_char dummy;
int emptymatch = 1;
/* flush the pipeline */
if (DoC_is_2000(doc)) {
dummy = ReadDOC(docptr, 2k_ECCStatus);
@ -994,7 +994,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
dummy = ReadDOC(docptr, ECCConf);
dummy = ReadDOC(docptr, ECCConf);
}
/* Error occured ? */
if (dummy & 0x80) {
for (i = 0; i < 6; i++) {
@ -1032,7 +1032,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc);
if (ret > 0)
printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);
}
}
if (DoC_is_MillenniumPlus(doc))
WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
else
@ -1043,16 +1043,16 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
}
return ret;
}
//u_char mydatabuf[528];
/*u_char mydatabuf[528]; */
static struct nand_oobinfo doc200x_oobinfo = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 6,
.eccpos = {0, 1, 2, 3, 4, 5},
.oobfree = { {8, 8} }
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 6,
.eccpos = {0, 1, 2, 3, 4, 5},
.oobfree = { {8, 8} }
};
/* Find the (I)NFTL Media Header, and optionally also the mirror media header.
On sucessful return, buf will contain a copy of the media header for
further processing. id is the string to scan for, and will presumably be
@ -1068,7 +1068,7 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf,
int ret;
size_t retlen;
end = min(end, mtd->size); // paranoia
end = min(end, mtd->size); /* paranoia */
for (offs = 0; offs < end; offs += mtd->erasesize) {
ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf);
if (retlen != mtd->oobblock) continue;
@ -1122,8 +1122,8 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out;
mh = (struct NFTLMediaHeader *) buf;
//#ifdef CONFIG_MTD_DEBUG_VERBOSE
// if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */
/* if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */
printk(KERN_INFO " DataOrgID = %s\n"
" NumEraseUnits = %d\n"
" FirstPhysicalEUN = %d\n"
@ -1132,7 +1132,7 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
mh->DataOrgID, mh->NumEraseUnits,
mh->FirstPhysicalEUN, mh->FormattedSize,
mh->UnitSizeFactor);
//#endif
/*#endif */
blocks = mtd->size >> this->phys_erase_shift;
maxblocks = min(32768U, mtd->erasesize - psize);
@ -1175,9 +1175,9 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
offs <<= this->page_shift;
offs += mtd->erasesize;
//parts[0].name = " DiskOnChip Boot / Media Header partition";
//parts[0].offset = 0;
//parts[0].size = offs;
/*parts[0].name = " DiskOnChip Boot / Media Header partition"; */
/*parts[0].offset = 0; */
/*parts[0].size = offs; */
parts[0].name = " DiskOnChip BDTL partition";
parts[0].offset = offs;
@ -1232,9 +1232,9 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits);
mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
//#ifdef CONFIG_MTD_DEBUG_VERBOSE
// if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */
/* if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */
printk(KERN_INFO " bootRecordID = %s\n"
" NoOfBootImageBlocks = %d\n"
" NoOfBinaryPartitions = %d\n"
@ -1252,7 +1252,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
((unsigned char *) &mh->OsakVersion)[2] & 0xf,
((unsigned char *) &mh->OsakVersion)[3] & 0xf,
mh->PercentUsed);
//#endif
/*#endif */
vshift = this->phys_erase_shift + mh->BlockMultiplierBits;
@ -1278,8 +1278,8 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
ip->spareUnits = le32_to_cpu(ip->spareUnits);
ip->Reserved0 = le32_to_cpu(ip->Reserved0);
//#ifdef CONFIG_MTD_DEBUG_VERBOSE
// if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */
/* if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */
printk(KERN_INFO " PARTITION[%d] ->\n"
" virtualUnits = %d\n"
" firstUnit = %d\n"
@ -1289,7 +1289,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
i, ip->virtualUnits, ip->firstUnit,
ip->lastUnit, ip->flags,
ip->spareUnits);
//#endif
/*#endif */
/*
if ((i == 0) && (ip->firstUnit > 0)) {
@ -1456,7 +1456,7 @@ static inline int __init doc2001_init(struct mtd_info *mtd)
ReadDOC(doc->virtadr, ChipID);
if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) {
/* It's not a Millennium; it's one of the newer
DiskOnChip 2000 units with a similar ASIC.
DiskOnChip 2000 units with a similar ASIC.
Treat it like a Millennium, except that it
can have multiple chips. */
doc2000_count_chips(mtd);
@ -1518,20 +1518,20 @@ static inline int __init doc_probe(unsigned long physadr)
* to the DOCControl register. So we store the current contents
* of the DOCControl register's location, in case we later decide
* that it's not a DiskOnChip, and want to put it back how we
* found it.
* found it.
*/
save_control = ReadDOC(virtadr, DOCControl);
/* Reset the DiskOnChip ASIC */
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
virtadr, DOCControl);
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
virtadr, DOCControl);
/* Enable the DiskOnChip ASIC */
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
virtadr, DOCControl);
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
virtadr, DOCControl);
ChipID = ReadDOC(virtadr, ChipID);
@ -1614,11 +1614,11 @@ static inline int __init doc_probe(unsigned long physadr)
if (ChipID == DOC_ChipID_DocMilPlus16) {
WriteDOC(~newval, virtadr, Mplus_AliasResolution);
oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution);
WriteDOC(newval, virtadr, Mplus_AliasResolution); // restore it
WriteDOC(newval, virtadr, Mplus_AliasResolution); /* restore it */
} else {
WriteDOC(~newval, virtadr, AliasResolution);
oldval = ReadDOC(doc->virtadr, AliasResolution);
WriteDOC(newval, virtadr, AliasResolution); // restore it
WriteDOC(newval, virtadr, AliasResolution); /* restore it */
}
newval = ~newval;
if (oldval == newval) {
@ -1726,7 +1726,7 @@ static int __init init_nanddoc(void)
int i, ret = 0;
/* We could create the decoder on demand, if memory is a concern.
* This way we have it handy, if an error happens
* This way we have it handy, if an error happens
*
* Symbolsize is 10 (bits)
* Primitve polynomial is x^10+x^3+1

File diff suppressed because it is too large Load Diff

@ -3,7 +3,7 @@
*
* Overview:
* Bad block table support for the NAND driver
*
*
* Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
*
* $Id: nand_bbt.c,v 1.28 2004/11/13 10:19:09 gleixner Exp $
@ -14,23 +14,23 @@
*
* Description:
*
* When nand_scan_bbt is called, then it tries to find the bad block table
* depending on the options in the bbt descriptor(s). If a bbt is found
* then the contents are read and the memory based bbt is created. If a
* When nand_scan_bbt is called, then it tries to find the bad block table
* depending on the options in the bbt descriptor(s). If a bbt is found
* then the contents are read and the memory based bbt is created. If a
* mirrored bbt is selected then the mirror is searched too and the
* versions are compared. If the mirror has a greater version number
* versions are compared. If the mirror has a greater version number
* than the mirror bbt is used to build the memory based bbt.
* If the tables are not versioned, then we "or" the bad block information.
* If one of the bbt's is out of date or does not exist it is (re)created.
* If no bbt exists at all then the device is scanned for factory marked
* good / bad blocks and the bad block tables are created.
* If one of the bbt's is out of date or does not exist it is (re)created.
* If no bbt exists at all then the device is scanned for factory marked
* good / bad blocks and the bad block tables are created.
*
* For manufacturer created bbts like the one found on M-SYS DOC devices
* For manufacturer created bbts like the one found on M-SYS DOC devices
* the bbt is searched and read but never created
*
* The autogenerated bad block table is located in the last good blocks
* of the device. The table is mirrored, so it can be updated eventually.
* The table is marked in the oob area with an ident pattern and a version
* The autogenerated bad block table is located in the last good blocks
* of the device. The table is mirrored, so it can be updated eventually.
* The table is marked in the oob area with an ident pattern and a version
* number which indicates which of both tables is more up to date.
*
* The table uses 2 bits per block
@ -43,13 +43,13 @@
* 01b: block is marked bad due to wear
* 10b: block is reserved (to protect the bbt area)
* 11b: block is factory marked bad
*
*
* Multichip devices like DOC store the bad block info per floor.
*
* Following assumptions are made:
* - bbts start at a page boundary, if autolocated on a block boundary
* - the space neccecary for a bbt in FLASH does not exceed a block boundary
*
*
*/
#include <common.h>
@ -63,7 +63,7 @@
#include <asm/errno.h>
/**
/**
* check_pattern - [GENERIC] check if a pattern is in the buffer
* @buf: the buffer to search
* @len: the length of buffer to search
@ -87,9 +87,9 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
if (p[i] != 0xff)
return -1;
}
}
}
p += end;
/* Compare the pattern */
for (i = 0; i < td->len; i++) {
if (p[i] != td->pattern[i])
@ -120,7 +120,7 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
* Read the bad block table starting from page.
*
*/
static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
int bits, int offs, int reserved_block_code)
{
int res, i, j, act = 0;
@ -131,7 +131,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
totlen = (num * bits) >> 3;
from = ((loff_t)page) << this->page_shift;
while (totlen) {
len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob);
@ -141,7 +141,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
return res;
}
printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
}
}
/* Analyse data */
for (i = 0; i < len; i++) {
@ -161,12 +161,12 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
* message to MTD_DEBUG_LEVEL0 */
printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
/* Factory marked bad or worn out ? */
/* Factory marked bad or worn out ? */
if (tmp == 0)
this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
else
this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06);
}
}
}
totlen -= len;
from += len;
@ -178,7 +178,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
* read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
* @mtd: MTD device structure
* @buf: temporary buffer
* @td: descriptor for the bad block table
* @td: descriptor for the bad block table
* @chip: read the table for a specific chip, -1 read all chips.
* Applies only if NAND_BBT_PERCHIP option is set
*
@ -213,7 +213,7 @@ static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
* read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
* @mtd: MTD device structure
* @buf: temporary buffer
* @td: descriptor for the bad block table
* @td: descriptor for the bad block table
* @md: descriptor for the bad block table mirror
*
* Read the bad block table(s) for all chips starting at a given page
@ -225,16 +225,16 @@ static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_de
{
struct nand_chip *this = mtd->priv;
/* Read the primary version, if available */
/* Read the primary version, if available */
if (td->options & NAND_BBT_VERSION) {
nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
td->version[0] = buf[mtd->oobblock + td->veroffs];
printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
}
/* Read the mirror version, if available */
/* Read the mirror version, if available */
if (md && (md->options & NAND_BBT_VERSION)) {
nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
md->version[0] = buf[mtd->oobblock + md->veroffs];
printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
}
@ -268,7 +268,7 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
else {
if (bd->options & NAND_BBT_SCAN2NDPAGE)
len = 2;
else
else
len = 1;
}
scanlen = mtd->oobblock + mtd->oobsize;
@ -285,20 +285,20 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
if (chip >= this->numchips) {
printk (KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
chip + 1, this->numchips);
return;
return;
}
numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
startblock = chip * numblocks;
numblocks += startblock;
from = startblock << (this->bbt_erase_shift - 1);
}
for (i = startblock; i < numblocks;) {
nand_read_raw (mtd, buf, from, readlen, ooblen);
for (j = 0; j < len; j++) {
if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
this->bbt[i >> 3] |= 0x03 << (i & 0x6);
printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
i >> 1, (unsigned int) from);
break;
}
@ -315,15 +315,15 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
* @td: descriptor for the bad block table
*
* Read the bad block table by searching for a given ident pattern.
* Search is preformed either from the beginning up or from the end of
* Search is preformed either from the beginning up or from the end of
* the device downwards. The search starts always at the start of a
* block.
* If the option NAND_BBT_PERCHIP is given, each chip is searched
* If the option NAND_BBT_PERCHIP is given, each chip is searched
* for a bbt, which contains the bad block information of this chip.
* This is neccecary to provide support for certain DOC devices.
*
* The bbt ident pattern resides in the oob area of the first page
* in a block.
* The bbt ident pattern resides in the oob area of the first page
* in a block.
*/
static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
{
@ -338,10 +338,10 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
startblock = (mtd->size >> this->bbt_erase_shift) -1;
dir = -1;
} else {
startblock = 0;
startblock = 0;
dir = 1;
}
}
/* Do we have a bbt per chip ? */
if (td->options & NAND_BBT_PERCHIP) {
chips = this->numchips;
@ -351,19 +351,19 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
chips = 1;
bbtblocks = mtd->size >> this->bbt_erase_shift;
}
/* Number of bits for each erase block in the bbt */
bits = td->options & NAND_BBT_NRBITS_MSK;
for (i = 0; i < chips; i++) {
/* Reset version information */
td->version[i] = 0;
td->version[i] = 0;
td->pages[i] = -1;
/* Scan the maximum number of blocks */
for (block = 0; block < td->maxblocks; block++) {
int actblock = startblock + dir * block;
/* Read first page */
nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
if (!check_pattern(buf, scanlen, mtd->oobblock, td)) {
td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift);
if (td->options & NAND_BBT_VERSION) {
@ -381,46 +381,46 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
else
printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]);
}
return 0;
return 0;
}
/**
* search_read_bbts - [GENERIC] scan the device for bad block table(s)
* @mtd: MTD device structure
* @buf: temporary buffer
* @td: descriptor for the bad block table
* @td: descriptor for the bad block table
* @md: descriptor for the bad block table mirror
*
* Search and read the bad block table(s)
*/
static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
struct nand_bbt_descr *td, struct nand_bbt_descr *md)
{
/* Search the primary table */
search_bbt (mtd, buf, td);
/* Search the mirror table */
if (md)
search_bbt (mtd, buf, md);
/* Force result check */
return 1;
return 1;
}
/**
/**
* write_bbt - [GENERIC] (Re)write the bad block table
*
* @mtd: MTD device structure
* @buf: temporary buffer
* @td: descriptor for the bad block table
* @td: descriptor for the bad block table
* @md: descriptor for the bad block table mirror
* @chipsel: selector for a specific chip, -1 for all
*
* (Re)write the bad block table
*
*/
static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel)
{
struct nand_chip *this = mtd->priv;
@ -439,7 +439,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
/* Write bad block table per chip rather than per device ? */
if (td->options & NAND_BBT_PERCHIP) {
numblocks = (int) (this->chipsize >> this->bbt_erase_shift);
/* Full device write or specific chip ? */
/* Full device write or specific chip ? */
if (chipsel == -1) {
nrchips = this->numchips;
} else {
@ -449,19 +449,19 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
} else {
numblocks = (int) (mtd->size >> this->bbt_erase_shift);
nrchips = 1;
}
}
/* Loop through the chips */
for (; chip < nrchips; chip++) {
/* There was already a version of the table, reuse the page
* This applies for absolute placement too, as we have the
/* There was already a version of the table, reuse the page
* This applies for absolute placement too, as we have the
* page nr. in td->pages.
*/
if (td->pages[chip] != -1) {
page = td->pages[chip];
goto write;
}
}
/* Automatic placement of the bad block table */
/* Search direction top -> down ? */
@ -471,7 +471,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
} else {
startblock = chip * numblocks;
dir = 1;
}
}
for (i = 0; i < td->maxblocks; i++) {
int block = startblock + dir * i;
@ -488,7 +488,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
}
printk (KERN_ERR "No space left to write bad block table\n");
return -ENOSPC;
write:
write:
/* Set up shift count and masks for the flash table */
bits = td->options & NAND_BBT_NRBITS_MSK;
@ -499,14 +499,14 @@ write:
case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break;
default: return -EINVAL;
}
bbtoffs = chip * (numblocks >> 2);
to = ((loff_t) page) << this->page_shift;
memcpy (&oobinfo, this->autooob, sizeof(oobinfo));
oobinfo.useecc = MTD_NANDECC_PLACEONLY;
/* Must we save the block contents ? */
if (td->options & NAND_BBT_SAVECONTENT) {
/* Make it block aligned */
@ -545,7 +545,7 @@ write:
buf[len + td->veroffs] = td->version[chip];
}
}
/* walk through the memory table */
for (i = 0; i < numblocks; ) {
uint8_t dat;
@ -557,7 +557,7 @@ write:
dat >>= 2;
}
}
memset (&einfo, 0, sizeof (einfo));
einfo.mtd = mtd;
einfo.addr = (unsigned long) to;
@ -567,18 +567,18 @@ write:
printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res);
return res;
}
res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
if (res < 0) {
printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res);
return res;
}
printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n",
printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n",
(unsigned int) to, td->version[chip]);
/* Mark it as used */
td->pages[chip] = page;
}
}
return 0;
}
@ -587,7 +587,7 @@ write:
* @mtd: MTD device structure
* @bd: descriptor for the good/bad block search pattern
*
* The function creates a memory based bbt by scanning the device
* The function creates a memory based bbt by scanning the device
* for manufacturer / software marked good / bad blocks
*/
static int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
@ -621,11 +621,11 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
struct nand_bbt_descr *rd, *rd2;
/* Do we have a bbt per chip ? */
if (td->options & NAND_BBT_PERCHIP)
if (td->options & NAND_BBT_PERCHIP)
chips = this->numchips;
else
else
chips = 1;
for (i = 0; i < chips; i++) {
writeops = 0;
rd = NULL;
@ -640,7 +640,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
}
if (td->pages[i] == -1) {
rd = md;
rd = md;
td->version[i] = md->version[i];
writeops = 1;
goto writecheck;
@ -658,7 +658,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
if (!(td->options & NAND_BBT_VERSION))
rd2 = md;
goto writecheck;
}
}
if (((int8_t) (td->version[i] - md->version[i])) > 0) {
rd = td;
@ -683,15 +683,15 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
create:
/* Create the bad block table by scanning the device ? */
if (!(td->options & NAND_BBT_CREATE))
continue;
continue;
/* Create the table in memory by scanning the chip(s) */
create_bbt (mtd, buf, bd, chipsel);
td->version[i] = 1;
if (md)
md->version[i] = 1;
writecheck:
md->version[i] = 1;
writecheck:
/* read back first ? */
if (rd)
read_abs_bbt (mtd, buf, rd, chipsel);
@ -705,7 +705,7 @@ writecheck:
if (res < 0)
return res;
}
/* Write the mirror bad block table to the device ? */
if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
res = write_bbt (mtd, buf, md, td, chipsel);
@ -713,11 +713,11 @@ writecheck:
return res;
}
}
return 0;
return 0;
}
/**
* mark_bbt_regions - [GENERIC] mark the bad block table regions
* mark_bbt_regions - [GENERIC] mark the bad block table regions
* @mtd: MTD device structure
* @td: bad block table descriptor
*
@ -738,14 +738,14 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
} else {
chips = 1;
nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
}
}
for (i = 0; i < chips; i++) {
if ((td->options & NAND_BBT_ABSPAGE) ||
!(td->options & NAND_BBT_WRITE)) {
if (td->pages[i] == -1) continue;
block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
block <<= 1;
block <<= 1;
oldval = this->bbt[(block >> 3)];
newval = oldval | (0x2 << (block & 0x06));
this->bbt[(block >> 3)] = newval;
@ -756,16 +756,16 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
update = 0;
if (td->options & NAND_BBT_LASTBLOCK)
block = ((i + 1) * nrblocks) - td->maxblocks;
else
else
block = i * nrblocks;
block <<= 1;
block <<= 1;
for (j = 0; j < td->maxblocks; j++) {
oldval = this->bbt[(block >> 3)];
newval = oldval | (0x2 << (block & 0x06));
this->bbt[(block >> 3)] = newval;
if (oldval != newval) update = 1;
block += 2;
}
}
/* If we want reserved blocks to be recorded to flash, and some
new ones have been marked, then we need to update the stored
bbts. This should only happen once. */
@ -779,7 +779,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
* @mtd: MTD device structure
* @bd: descriptor for the good/bad block search pattern
*
* The function checks, if a bad block table(s) is/are already
* The function checks, if a bad block table(s) is/are already
* available. If not it scans the device for manufacturer
* marked good / bad blocks and writes the bad block table(s) to
* the selected place.
@ -822,30 +822,30 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
this->bbt = NULL;
return -ENOMEM;
}
/* Is the bbt at a given page ? */
if (td->options & NAND_BBT_ABSPAGE) {
res = read_abs_bbts (mtd, buf, td, md);
} else {
} else {
/* Search the bad block table using a pattern in oob */
res = search_read_bbts (mtd, buf, td, md);
}
}
if (res)
if (res)
res = check_create (mtd, buf, bd);
/* Prevent the bbt regions from erasing / writing */
mark_bbt_region (mtd, td);
if (md)
mark_bbt_region (mtd, md);
kfree (buf);
return res;
}
/**
* nand_update_bbt - [NAND Interface] update bad block table(s)
* nand_update_bbt - [NAND Interface] update bad block table(s)
* @mtd: MTD device structure
* @offs: the offset of the newly marked block
*
@ -872,7 +872,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
printk (KERN_ERR "nand_update_bbt: Out of memory\n");
return -ENOMEM;
}
writeops = md != NULL ? 0x03 : 0x01;
/* Do we have a bbt per chip ? */
@ -886,7 +886,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
td->version[chip]++;
if (md)
md->version[chip]++;
md->version[chip]++;
/* Write the bad block table to the device ? */
if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
@ -899,15 +899,15 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
res = write_bbt (mtd, buf, md, td, chipsel);
}
out:
out:
kfree (buf);
return res;
}
/* Define some generic bad / good block scan pattern which are used
/* Define some generic bad / good block scan pattern which are used
* while scanning a device for factory marked good / bad blocks
*
* The memory based patterns just
*
* The memory based patterns just
*/
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
@ -954,7 +954,7 @@ static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
static struct nand_bbt_descr bbt_main_descr = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
.offs = 8,
.len = 4,
@ -964,7 +964,7 @@ static struct nand_bbt_descr bbt_main_descr = {
};
static struct nand_bbt_descr bbt_mirror_descr = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
.offs = 8,
.len = 4,
@ -974,7 +974,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
};
/**
* nand_default_bbt - [NAND Interface] Select a default bad block table for the device
* nand_default_bbt - [NAND Interface] Select a default bad block table for the device
* @mtd: MTD device structure
*
* This function selects the default bad block table
@ -984,29 +984,29 @@ static struct nand_bbt_descr bbt_mirror_descr = {
int nand_default_bbt (struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
/* Default for AG-AND. We must use a flash based
/* Default for AG-AND. We must use a flash based
* bad block table as the devices have factory marked
* _good_ blocks. Erasing those blocks leads to loss
* of the good / bad information, so we _must_ store
* this information in a good / bad table during
* this information in a good / bad table during
* startup
*/
if (this->options & NAND_IS_AND) {
/* Use the default pattern descriptors */
if (!this->bbt_td) {
if (!this->bbt_td) {
this->bbt_td = &bbt_main_descr;
this->bbt_md = &bbt_mirror_descr;
}
}
this->options |= NAND_USE_FLASH_BBT;
return nand_scan_bbt (mtd, &agand_flashbased);
}
/* Is a flash based bad block table requested ? */
if (this->options & NAND_USE_FLASH_BBT) {
/* Use the default pattern descriptors */
if (!this->bbt_td) {
/* Use the default pattern descriptors */
if (!this->bbt_td) {
this->bbt_td = &bbt_main_descr;
this->bbt_md = &bbt_mirror_descr;
}
@ -1026,23 +1026,23 @@ int nand_default_bbt (struct mtd_info *mtd)
}
/**
* nand_isbad_bbt - [NAND Interface] Check if a block is bad
* nand_isbad_bbt - [NAND Interface] Check if a block is bad
* @mtd: MTD device structure
* @offs: offset in the device
* @allowbbt: allow access to bad block table region
*
*/
*/
int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
{
struct nand_chip *this = mtd->priv;
int block;
uint8_t res;
/* Get block number * 2 */
block = (int) (offs >> (this->bbt_erase_shift - 1));
res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
(unsigned int)offs, res, block >> 1);
switch ((int)res) {

@ -13,16 +13,16 @@
* 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
@ -30,7 +30,7 @@
* 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.
*/
@ -66,7 +66,7 @@ static const u_char nand_ecc_precalc_table[] = {
* nand_trans_result - [GENERIC] create non-inverted ECC
* @reg2: line parity reg 2
* @reg3: line parity reg 3
* @ecc_code: ecc
* @ecc_code: ecc
*
* Creates non-inverted ECC code from line parity
*/
@ -74,11 +74,11 @@ 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] */
@ -89,7 +89,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
b >>= 1;
a >>= 1;
}
/* Calculate second ECC byte */
b = 0x80;
for (i = 0; i < 4; i++) {
@ -101,7 +101,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
b >>= 1;
a >>= 1;
}
/* Store two of the ECC bytes */
ecc_code[0] = tmp1;
ecc_code[1] = tmp2;
@ -117,28 +117,28 @@ 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 */
/* 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];
@ -158,12 +158,12 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
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 */
/* 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;
@ -172,7 +172,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
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;
@ -205,8 +205,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
a ^= (b << bit);
dat[add] = a;
return 1;
}
else {
} else {
i = 0;
while (d1) {
if (d1 & 0x01)
@ -236,7 +235,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
}
}
}
/* Should never happen */
return -1;
}

@ -18,14 +18,14 @@
/*
* 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
* 512 512 Byte page size
*/
struct nand_flash_dev nand_flash_ids[] = {
{"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0},
@ -38,36 +38,36 @@ struct nand_flash_dev nand_flash_ids[] = {
{"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
*/
@ -82,13 +82,13 @@ struct nand_flash_dev nand_flash_ids[] = {
{"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},
@ -101,11 +101,11 @@ struct nand_flash_dev nand_flash_ids[] = {
{"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 !
/* 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
* 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},

@ -143,7 +143,7 @@
/* keeps pointer to currentlu processed partition */
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
*
@ -290,7 +290,7 @@ static inline void *get_fl_mem(u32 off, u32 size, void *ext_buf)
return get_fl_mem_nor(off);
#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)
return get_fl_mem_nand(off, size, ext_buf);
#endif
@ -308,7 +308,7 @@ static inline void *get_node_mem(u32 off)
return get_node_mem_nor(off);
#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)
return get_node_mem_nand(off);
#endif
@ -319,7 +319,7 @@ static inline void *get_node_mem(u32 off)
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;
if (id->type == MTD_DEV_TYPE_NAND)

@ -1,6 +1,6 @@
#include <common.h>
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
#if defined(CONFIG_NEW_NAND_CODE) && (CONFIG_COMMANDS & CFG_CMD_JFFS2)
#include <malloc.h>
#include <linux/stat.h>
@ -12,12 +12,12 @@
#include "jffs2_nand_private.h"
#define NODE_CHUNK 1024 /* size of memory allocation chunk in b_nodes */
#define NODE_CHUNK 1024 /* size of memory allocation chunk in b_nodes */
/* Debugging switches */
#undef DEBUG_DIRENTS /* print directory entry list after scan */
#undef DEBUG_FRAGMENTS /* print fragment list after scan */
#undef DEBUG /* enable debugging messages */
#undef DEBUG /* enable debugging messages */
#ifdef DEBUG
# define DEBUGF(fmt,args...) printf(fmt ,##args)
@ -25,7 +25,6 @@
# define DEBUGF(fmt,args...)
#endif
static int nanddev = -1; /* nand device of current partition */
static nand_info_t *nand;
/* Compression names */
@ -385,10 +384,10 @@ jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino)
continue;
if (jDir->version == version && inode != 0) {
/* I'm pretty sure this isn't legal */
/* I'm pretty sure this isn't legal */
putstr(" ** ERROR ** ");
// putnstr(jDir->name, jDir->nsize);
// putLabeledWord(" has dup version =", version);
/* putnstr(jDir->name, jDir->nsize); */
/* putLabeledWord(" has dup version =", version); */
}
inode = jDir->ino;
version = jDir->version;
@ -574,15 +573,15 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino)
/* we need to search all and return the inode with the highest version */
for (jDir = (struct b_dirent *)pL->dir.listHead; jDir; jDir = jDir->next) {
if (ino == jDir->ino) {
if (jDir->version < version)
if (jDir->version < version)
continue;
if (jDir->version == version && jDirFoundType) {
/* I'm pretty sure this isn't legal */
/* I'm pretty sure this isn't legal */
putstr(" ** ERROR ** ");
// putnstr(jDir->name, jDir->nsize);
// putLabeledWord(" has dup version (resolve) = ",
// version);
/* putnstr(jDir->name, jDir->nsize); */
/* putLabeledWord(" has dup version (resolve) = ", */
/* version); */
}
jDirFoundType = jDir->type;
@ -686,12 +685,6 @@ jffs2_1pass_rescan_needed(struct part_info *part)
return 1;
}
#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND)
if (nanddev != (int)part->usr_priv - 1) {
DEBUGF ("rescan: nand device changed\n");
return -1;
}
#endif /* defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */
/* FIXME */
#if 0
/* but suppose someone reflashed a partition at the same offset... */
@ -806,10 +799,8 @@ jffs2_1pass_build_lists(struct part_info * part)
u32 counterF = 0;
u32 counterN = 0;
#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND)
nanddev = (int)part->usr_priv - 1;
nand = &nand_info[nanddev];
#endif /* defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */
struct mtdids *id = part->dev->id;
nand = nand_info + id->num;
/* if we are building a list we need to refresh the cache. */
jffs_init_1pass_list(part);
@ -993,7 +984,7 @@ jffs2_1pass_load(char *dest, struct part_info * part, const char *fname)
long ret = 0;
u32 inode;
if (! (pl = jffs2_get_list(part, "load")))
if (! (pl = jffs2_get_list(part, "load")))
return 0;
if (! (inode = jffs2_1pass_search_inode(pl, fname, 1))) {
@ -1025,7 +1016,7 @@ jffs2_1pass_info(struct part_info * part)
struct b_lists *pl;
int i;
if (! (pl = jffs2_get_list(part, "info")))
if (! (pl = jffs2_get_list(part, "info")))
return 0;
jffs2_1pass_fill_info(pl, &info);

@ -58,6 +58,14 @@ extern void __raw_readsl(unsigned int addr, void *data, int longlen);
#define __raw_readw(a) __arch_getw(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
* properly. Spell it out to the compiler in some cases.

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

@ -1,7 +1,7 @@
/*
* $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
* Portions of MTD ABI definition which are shared by kernel and user space
*/
#ifndef __MTD_ABI_H__
@ -27,17 +27,17 @@ struct mtd_oob_buf {
#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
#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
/* 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)
@ -45,31 +45,31 @@ struct mtd_oob_buf {
#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
/* 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
#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 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 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,
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 */

@ -1,4 +1,4 @@
/*
/*
* $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.
@ -46,7 +46,7 @@ struct mtd_erase_region_info {
struct mtd_info {
u_char type;
u_int32_t flags;
u_int32_t size; // Total size of the MTD
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
@ -54,25 +54,25 @@ struct mtd_info {
*/
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 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.
/* Kernel-only stuff starts here. */
char *name;
int index;
// oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO)
/* 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.
* it means that the whole device has erasesize as given above.
*/
int numeraseregions;
struct mtd_erase_region_info *eraseregions;
struct mtd_erase_region_info *eraseregions;
/* This really shouldn't be here. It can go away in 2.5 */
u_int32_t bank_size;
@ -95,10 +95,10 @@ struct mtd_info {
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
/*
* 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.
* 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);
@ -109,14 +109,14 @@ struct mtd_info {
#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
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,
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,
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 */
@ -179,7 +179,7 @@ int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs,
#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)
#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0)
#ifdef CONFIG_MTD_PARTITIONS

@ -24,7 +24,7 @@
* 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
* 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
@ -36,14 +36,14 @@
* 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
* 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
* 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
@ -120,7 +120,7 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
#define NAND_STATUS_READY 0x40
#define NAND_STATUS_WP 0x80
/*
/*
* Constants for ECC_MODES
*/
@ -162,12 +162,12 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
#define NAND_CACHEPRG 0x00000008
/* Chip has copy back function */
#define NAND_COPYBACK 0x00000010
/* AND Chip which has 4 banks and a confusing page / block
/* 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
#define NAND_4PAGE_ARRAY 0x00000040
/* Options valid for Samsung large page devices */
#define NAND_SAMSUNG_LP_OPTIONS \
@ -186,8 +186,8 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
/* 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
/* 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
@ -218,7 +218,7 @@ 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
* @lock: protection lock
* @active: the mtd device which holds the controller currently
*/
struct nand_hw_control {
@ -229,8 +229,8 @@ struct nand_hw_control {
/**
* 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
* @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
@ -253,7 +253,7 @@ struct nand_hw_control {
* 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
* @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
@ -265,7 +265,7 @@ struct nand_hw_control {
* @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
* @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
@ -280,20 +280,20 @@ struct nand_hw_control {
* @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
* @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);
@ -358,7 +358,7 @@ struct nand_chip {
* @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
* 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.
@ -387,7 +387,7 @@ struct nand_manufacturers {
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
@ -398,14 +398,14 @@ extern struct nand_manufacturers nand_manuf_ids[];
* @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
* 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 /
* @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
* 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.

@ -24,7 +24,7 @@
#ifndef _NAND_H_
#define _NAND_H_
#include <linux_compat.h>
#include <linux/mtd/compat.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>

Loading…
Cancel
Save