diff options
Diffstat (limited to 'recipes/u-boot/u-boot-mkimage-openmoko-native/uboot-s3c2410-nand.patch')
-rw-r--r-- | recipes/u-boot/u-boot-mkimage-openmoko-native/uboot-s3c2410-nand.patch | 525 |
1 files changed, 525 insertions, 0 deletions
diff --git a/recipes/u-boot/u-boot-mkimage-openmoko-native/uboot-s3c2410-nand.patch b/recipes/u-boot/u-boot-mkimage-openmoko-native/uboot-s3c2410-nand.patch new file mode 100644 index 0000000000..9c10edc958 --- /dev/null +++ b/recipes/u-boot/u-boot-mkimage-openmoko-native/uboot-s3c2410-nand.patch @@ -0,0 +1,525 @@ +This patch adds NAND (including boot-from-NAND via steppingstone) support to +the S3C2410 SoC code in u-boot + +Signed-off-by: Harald Welte <laforge@openmoko.org> + +Index: u-boot/cpu/arm920t/s3c24x0/Makefile +=================================================================== +--- u-boot.orig/cpu/arm920t/s3c24x0/Makefile 2007-02-28 03:47:44.000000000 +0100 ++++ u-boot/cpu/arm920t/s3c24x0/Makefile 2007-03-01 14:29:32.000000000 +0100 +@@ -26,7 +26,7 @@ + LIB = $(obj)lib$(SOC).a + + COBJS = i2c.o interrupts.o serial.o speed.o \ +- usb_ohci.o ++ usb_ohci.o nand_read.o nand.o + + SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) + OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +Index: u-boot/cpu/arm920t/s3c24x0/nand.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ u-boot/cpu/arm920t/s3c24x0/nand.c 2007-03-01 14:30:27.000000000 +0100 +@@ -0,0 +1,225 @@ ++/* ++ * (C) Copyright 2006 Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * ++ * 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 ++#define DEBUGN printf ++#else ++#define DEBUGN(x, args ...) {} ++#endif ++ ++#if (CONFIG_COMMANDS & CFG_CMD_NAND) ++#if !defined(CFG_NAND_LEGACY) ++ ++#include <nand.h> ++#include <s3c2410.h> ++ ++#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 NFECC0 __REGb(NF_BASE + 0x14) ++#define NFECC1 __REGb(NF_BASE + 0x15) ++#define NFECC2 __REGb(NF_BASE + 0x16) ++ ++#define S3C2410_NFCONF_EN (1<<15) ++#define S3C2410_NFCONF_512BYTE (1<<14) ++#define S3C2410_NFCONF_4STEP (1<<13) ++#define S3C2410_NFCONF_INITECC (1<<12) ++#define S3C2410_NFCONF_nFCE (1<<11) ++#define S3C2410_NFCONF_TACLS(x) ((x)<<8) ++#define S3C2410_NFCONF_TWRPH0(x) ((x)<<4) ++#define S3C2410_NFCONF_TWRPH1(x) ((x)<<0) ++ ++static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd) ++{ ++ struct nand_chip *chip = mtd->priv; ++ ++ DEBUGN("hwcontrol(): 0x%02x: ", cmd); ++ ++ switch (cmd) { ++ case NAND_CTL_SETNCE: ++ NFCONF &= ~S3C2410_NFCONF_nFCE; ++ DEBUGN("NFCONF=0x%08x\n", NFCONF); ++ break; ++ case NAND_CTL_CLRNCE: ++ NFCONF |= S3C2410_NFCONF_nFCE; ++ DEBUGN("NFCONF=0x%08x\n", NFCONF); ++ break; ++ case NAND_CTL_SETALE: ++ chip->IO_ADDR_W = NF_BASE + 0x8; ++ DEBUGN("SETALE\n"); ++ break; ++ case NAND_CTL_SETCLE: ++ chip->IO_ADDR_W = NF_BASE + 0x4; ++ DEBUGN("SETCLE\n"); ++ break; ++ default: ++ chip->IO_ADDR_W = NF_BASE + 0xc; ++ break; ++ } ++ return; ++} ++ ++static int s3c2410_dev_ready(struct mtd_info *mtd) ++{ ++ DEBUGN("dev_ready\n"); ++ return (NFSTAT & 0x01); ++} ++ ++static void s3c2410_cmdfunc(struct mtd_info *mtd, unsigned cmd, ++ int column, int page_addr) ++{ ++ DEBUGN("cmdfunc(): 0x%02x, col=%d, page=%d\n", cmd, column, page_addr); ++ ++ switch (cmd) { ++ case NAND_CMD_READ0: ++ case NAND_CMD_READ1: ++ case NAND_CMD_READOOB: ++ NFCMD = cmd; ++ NFADDR = column & 0xff; ++ NFADDR = page_addr & 0xff; ++ NFADDR = (page_addr >> 8) & 0xff; ++ NFADDR = (page_addr >> 16) & 0xff; ++ break; ++ case NAND_CMD_READID: ++ NFCMD = cmd; ++ NFADDR = 0; ++ break; ++ case NAND_CMD_PAGEPROG: ++ NFCMD = cmd; ++ printf("PAGEPROG not implemented\n"); ++ break; ++ case NAND_CMD_ERASE1: ++ NFCMD = cmd; ++ NFADDR = page_addr & 0xff; ++ NFADDR = (page_addr >> 8) & 0xff; ++ NFADDR = (page_addr >> 16) & 0xff; ++ break; ++ case NAND_CMD_ERASE2: ++ NFCMD = cmd; ++ break; ++ case NAND_CMD_SEQIN: ++ printf("SEQIN not implemented\n"); ++ break; ++ case NAND_CMD_STATUS: ++ NFCMD = cmd; ++ break; ++ case NAND_CMD_RESET: ++ NFCMD = cmd; ++ break; ++ default: ++ break; ++ } ++ ++ while (!s3c2410_dev_ready(mtd)); ++} ++ ++#ifdef CONFIG_S3C2410_NAND_HWECC ++void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode) ++{ ++ DEBUGN("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd ,mode); ++ NFCONF |= S3C2410_NFCONF_INITECC; ++} ++ ++static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) ++{ ++ ecc_code[0] = NFECC0; ++ ecc_code[1] = NFECC1; ++ ecc_code[2] = NFECC2; ++ DEBUGN("s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n", mtd , ecc_code[0], ecc_code[1], ecc_code[2]); ++ ++ return 0; ++} ++ ++int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) ++{ ++ if (read_ecc[0] == calc_ecc[0] && ++ read_ecc[1] == calc_ecc[1] && ++ read_ecc[2] == calc_ecc[2]) ++ return 0; ++ ++ printf("s3c2410_nand_correct_data: not implemented\n"); ++ return -1; ++} ++#endif ++ ++int board_nand_init(struct nand_chip *nand) ++{ ++ u_int32_t cfg; ++ u_int8_t tacls, twrph0, twrph1; ++ S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER(); ++ ++ DEBUGN("board_nand_init()\n"); ++ ++ clk_power->CLKCON |= (1 << 4); ++ ++ /* initialize hardware */ ++ twrph0 = 3; twrph1 = 0; tacls = 0; ++ ++ cfg = S3C2410_NFCONF_EN; ++ cfg |= S3C2410_NFCONF_TACLS(tacls - 1); ++ cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); ++ cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); ++ ++ NFCONF = cfg; ++ //NFCONF = 0xf842; ++ ++ /* initialize nand_chip data structure */ ++ nand->IO_ADDR_R = nand->IO_ADDR_W = 0x4e00000c; ++ ++ /* read_buf and write_buf are default */ ++ /* read_byte and write_byte are default */ ++ ++ /* hwcontrol always must be implemented */ ++ nand->hwcontrol = s3c2410_hwcontrol; ++ ++ nand->dev_ready = s3c2410_dev_ready; ++ ++#ifdef CONFIG_S3C2410_NAND_HWECC ++ nand->enable_hwecc = s3c2410_nand_enable_hwecc; ++ nand->calculate_ecc = s3c2410_nand_calculate_ecc; ++ nand->correct_data = s3c2410_nand_correct_data; ++ nand->eccmode = NAND_ECC_HW3_512; ++#else ++ nand->eccmode = NAND_ECC_SOFT; ++#endif ++ ++#ifdef CONFIG_S3C2410_NAND_BBT ++ nand->options = NAND_USE_FLASH_BBT; ++#else ++ nand->options = 0; ++#endif ++ ++ DEBUGN("end of nand_init\n"); ++ ++ return 0; ++} ++ ++#else ++ #error "U-Boot legacy NAND support not available for S3C2410" ++#endif ++#endif +Index: u-boot/cpu/arm920t/s3c24x0/nand_read.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ u-boot/cpu/arm920t/s3c24x0/nand_read.c 2007-02-28 03:51:24.000000000 +0100 +@@ -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 <hwang@mizi.com> ++ * Date : $Date: 2004/02/04 10:37:37 $ ++ * ++ * u-boot integration and bad-block skipping (C) 2006 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ */ ++ ++#include <common.h> ++ ++#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 2007-02-28 03:47:44.000000000 +0100 ++++ u-boot/cpu/arm920t/start.S 2007-03-01 14:29:22.000000000 +0100 +@@ -5,6 +5,10 @@ + * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> + * Copyright (c) 2002 Gary Jennejohn <gj@denx.de> + * ++ * S3C2410 NAND portions ++ * Copyright (c) 2001 MIZI Research, Inc. ++ * Copyright (c) 2006 Openmoko, Inc. (Harald Welte <laforge@openmmoko.org> ++ * + * See file CREDITS for list of people who contributed to this + * project. + * +@@ -27,6 +31,7 @@ + + #include <config.h> + #include <version.h> ++#include <s3c2410.h> + + + /* +@@ -161,6 +166,7 @@ + #endif + + #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 */ +@@ -177,6 +183,93 @@ + 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] ++ ++#if 0 ++ @ get ready to call C functions (for nand_read()) ++ ldr sp, DW_STACK_START @ setup stack pointer ++ mov fp, #0 @ no previous frame, so fp=0 ++#else ++ 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 */ ++#endif ++ ++ @ 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 */ + + /* Set up the stack */ +Index: u-boot/include/s3c2410.h +=================================================================== +--- u-boot.orig/include/s3c2410.h 2007-02-28 03:51:24.000000000 +0100 ++++ u-boot/include/s3c2410.h 2007-03-01 14:29:22.000000000 +0100 +@@ -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 <s3c24x0.h> + ++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)) |