Index: u-boot/cpu/arm920t/s3c24x0/nand_read.c =================================================================== --- /dev/null +++ u-boot/cpu/arm920t/s3c24x0/nand_read.c @@ -0,0 +1,98 @@ +/* + * nand_read.c: Simple NAND read functions for booting from NAND + * + * This is used by cpu/arm920/start.S assembler code, + * and the board-specific linker script must make sure this + * file is linked within the first 4kB of NAND flash. + * + * Taken from GPLv2 licensed vivi bootloader, + * Copyright (C) 2002 MIZI Research, Inc. + * + * Author: Hwang, Chideok + * Date : $Date: 2004/02/04 10:37:37 $ + * + * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc. + * Author: Harald Welte + */ + +#include + +#ifdef CONFIG_S3C2410_NAND_BOOT + +#define __REGb(x) (*(volatile unsigned char *)(x)) +#define __REGi(x) (*(volatile unsigned int *)(x)) +#define NF_BASE 0x4e000000 +#define NFCONF __REGi(NF_BASE + 0x0) +#define NFCMD __REGb(NF_BASE + 0x4) +#define NFADDR __REGb(NF_BASE + 0x8) +#define NFDATA __REGb(NF_BASE + 0xc) +#define NFSTAT __REGb(NF_BASE + 0x10) + +#define BUSY 1 +inline void wait_idle(void) +{ + int i; + + while (!(NFSTAT & BUSY)) + for (i=0; i<10; i++); +} + +#define NAND_SECTOR_SIZE 512 +#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1) +#define NAND_PAGE_SIZE 0x4000 + +/* low level nand read function */ +int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) +{ + int i, j; + + if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) + return -1; /* invalid alignment */ + + /* chip Enable */ + NFCONF &= ~0x800; + for (i=0; i<10; i++); + + for (i=start_addr; i < (start_addr + size);) { +#ifdef CONFIG_S3C2410_NAND_SKIP_BAD + if (start_addr % NAND_PAGE_SIZE == 0) { + unsigned char data; + NFCMD = 0x50; + NFADDR = 517&0xf; + NFADDR = (i >> 9) & 0xff; + NFADDR = (i >> 17) & 0xff; + NFADDR = (i >> 25) & 0xff; + wait_idle(); + data = (NFDATA & 0xff); + if (data != 0xff) { + /* Bad block */ + i += NAND_PAGE_SIZE; + size += NAND_PAGE_SIZE; + continue; + } + } +#endif + /* READ0 */ + NFCMD = 0; + + /* Write Address */ + NFADDR = i & 0xff; + NFADDR = (i >> 9) & 0xff; + NFADDR = (i >> 17) & 0xff; + NFADDR = (i >> 25) & 0xff; + + wait_idle(); + + for (j=0; j < NAND_SECTOR_SIZE; j++, i++) { + *buf = (NFDATA & 0xff); + buf++; + } + } + + /* chip Disable */ + NFCONF |= 0x800; /* chip disable */ + + return 0; +} + +#endif /* CONFIG_S3C2410_NAND_BOOT */ Index: u-boot/cpu/arm920t/start.S =================================================================== --- u-boot.orig/cpu/arm920t/start.S +++ u-boot/cpu/arm920t/start.S @@ -5,6 +5,10 @@ * Copyright (c) 2002 Alex Züpke * Copyright (c) 2002 Gary Jennejohn * + * S3C2410 NAND portions + * Copyright (c) 2001 MIZI Research, Inc. + * Copyright (c) 2006 OpenMoko, Inc. (Harald Welte + * * See file CREDITS for list of people who contributed to this * project. * @@ -27,6 +31,7 @@ #include #include +#include #include /* @@ -116,8 +121,13 @@ orr r0,r0,#0xd3 msr cpsr,r0 + /* in case we run from the s3c24xx NAND stepping stone, the symbols + * for LED support are in lib_arm/board.o, i.e. outside of the + * steppingstone */ +#ifndef CONFIG_S3C2410_NAND_BOOT bl coloured_LED_init bl red_LED_on +#endif #if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) || defined(CONFIG_AT91RM9200DF) /* @@ -178,9 +188,10 @@ bl cpu_init_crit #endif -#ifdef CONFIG_AT91RM9200 +#if defined(CONFIG_AT91RM9200) || defined(CONFIG_S3C2410) #ifndef CONFIG_SKIP_RELOCATE_UBOOT +#ifndef CONFIG_S3C2410_NAND_BOOT relocate: /* relocate U-Boot to RAM */ adr r0, _start /* r0 <- current position of code */ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ @@ -197,6 +208,87 @@ stmia r1!, {r3-r10} /* copy to target address [r1] */ cmp r0, r2 /* until source end addreee [r2] */ ble copy_loop +#else /* NAND_BOOT */ +relocate: +copy_myself: + /* mov r10, lr */ + + @ reset NAND + mov r1, #S3C2410_NAND_BASE + ldr r2, =0xf842 @ initial value enable tacls=3,rph0=6,rph1=0 + str r2, [r1, #oNFCONF] + ldr r2, [r1, #oNFCONF] + bic r2, r2, #0x800 @ enable chip + str r2, [r1, #oNFCONF] + mov r2, #0xff @ RESET command + strb r2, [r1, #oNFCMD] + mov r3, #0 @ wait +1: add r3, r3, #0x1 + cmp r3, #0xa + blt 1b +2: ldr r2, [r1, #oNFSTAT] @ wait ready + tst r2, #0x1 + beq 2b + ldr r2, [r1, #oNFCONF] + orr r2, r2, #0x800 @ disable chip + str r2, [r1, #oNFCONF] + + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ + sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif + sub sp, r0, #12 /* leave 3 words for abort-stack */ + + @ copy u-boot to RAM + ldr r0, _TEXT_BASE + mov r1, #0x0 + mov r2, #CFG_UBOOT_SIZE + bl nand_read_ll + + tst r0, #0x0 + beq ok_nand_read +#ifdef CONFIG_DEBUG_LL +bad_nand_read: + ldr r0, STR_FAIL + ldr r1, SerBase + bl PrintWord +1: b 1b @ infinite loop +#endif + +ok_nand_read: +#ifdef CONFIG_DEBUG_LL + ldr r0, STR_OK + ldr r1, SerBase + bl PrintWord +#endif + + @ verify + mov r0, #0 + @ldr r1, =0x33f00000 + ldr r1, _TEXT_BASE + mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes +go_next: + ldr r3, [r0], #4 + ldr r4, [r1], #4 + teq r3, r4 + bne notmatch + subs r2, r2, #4 + beq done_nand_read + bne go_next +notmatch: +#ifdef CONFIG_DEBUG_LL + sub r0, r0, #4 + ldr r1, SerBase + bl PrintHexWord + ldr r0, STR_FAIL + ldr r1, SerBase + bl PrintWord +#endif +1: b 1b +done_nand_read: +#endif /* NAND_BOOT */ #endif /* CONFIG_SKIP_RELOCATE_UBOOT */ #endif /* Set up the stack */ Index: u-boot/include/s3c2410.h =================================================================== --- u-boot.orig/include/s3c2410.h +++ u-boot/include/s3c2410.h @@ -38,12 +38,6 @@ #define S3C2410_ECCSIZE 512 #define S3C2410_ECCBYTES 3 -typedef enum { - S3C24X0_UART0, - S3C24X0_UART1, - S3C24X0_UART2 -} S3C24X0_UARTS_NR; - /* S3C2410 device base addresses */ #define S3C24X0_MEMCTL_BASE 0x48000000 #define S3C24X0_USB_HOST_BASE 0x49000000 @@ -65,9 +59,23 @@ #define S3C2410_SDI_BASE 0x5A000000 +#define oNFCONF 0x00 +#define oNFCMD 0x04 +#define oNFADDR 0x08 +#define oNFDATA 0x0C +#define oNFSTAT 0x10 +#define oNFECC 0x14 + +#ifndef __ASSEMBLER__ + /* include common stuff */ #include +typedef enum { + S3C24X0_UART0, + S3C24X0_UART1, + S3C24X0_UART2 +} S3C24X0_UARTS_NR; static inline S3C24X0_MEMCTL * S3C24X0_GetBase_MEMCTL(void) { @@ -142,6 +150,7 @@ return (S3C2410_SDI * const)S3C2410_SDI_BASE; } +#endif /* ISR */ #define pISR_RESET (*(unsigned *)(_ISR_STARTADDRESS+0x0)) Index: u-boot/cpu/arm920t/s3c24x0/Makefile =================================================================== --- u-boot.orig/cpu/arm920t/s3c24x0/Makefile +++ u-boot/cpu/arm920t/s3c24x0/Makefile @@ -26,7 +26,7 @@ LIB = $(obj)lib$(SOC).a COBJS = i2c.o interrupts.o serial.o speed.o \ - usb.o usb_ohci.o nand.o + usb.o usb_ohci.o nand_read.o nand.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))