summaryrefslogtreecommitdiffstats
path: root/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-nand.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-nand.patch')
-rw-r--r--meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-nand.patch525
1 files changed, 525 insertions, 0 deletions
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-nand.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-nand.patch
new file mode 100644
index 0000000000..dc363bbbab
--- /dev/null
+++ b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-nand.patch
@@ -0,0 +1,525 @@
1This patch adds NAND (including boot-from-NAND via steppingstone) support to
2the S3C2410 SoC code in u-boot
3
4Signed-off-by: Harald Welte <laforge@openmoko.org>
5
6Index: u-boot/cpu/arm920t/s3c24x0/Makefile
7===================================================================
8--- u-boot.orig/cpu/arm920t/s3c24x0/Makefile 2007-02-28 03:47:44.000000000 +0100
9+++ u-boot/cpu/arm920t/s3c24x0/Makefile 2007-03-01 14:29:32.000000000 +0100
10@@ -26,7 +26,7 @@
11 LIB = $(obj)lib$(SOC).a
12
13 COBJS = i2c.o interrupts.o serial.o speed.o \
14- usb_ohci.o
15+ usb_ohci.o nand_read.o nand.o
16
17 SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
18 OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
19Index: u-boot/cpu/arm920t/s3c24x0/nand.c
20===================================================================
21--- /dev/null 1970-01-01 00:00:00.000000000 +0000
22+++ u-boot/cpu/arm920t/s3c24x0/nand.c 2007-03-01 14:30:27.000000000 +0100
23@@ -0,0 +1,225 @@
24+/*
25+ * (C) Copyright 2006 OpenMoko, Inc.
26+ * Author: Harald Welte <laforge@openmoko.org>
27+ *
28+ * This program is free software; you can redistribute it and/or
29+ * modify it under the terms of the GNU General Public License as
30+ * published by the Free Software Foundation; either version 2 of
31+ * the License, or (at your option) any later version.
32+ *
33+ * This program is distributed in the hope that it will be useful,
34+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
35+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36+ * GNU General Public License for more details.
37+ *
38+ * You should have received a copy of the GNU General Public License
39+ * along with this program; if not, write to the Free Software
40+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
41+ * MA 02111-1307 USA
42+ */
43+
44+#include <common.h>
45+
46+#if 0
47+#define DEBUGN printf
48+#else
49+#define DEBUGN(x, args ...) {}
50+#endif
51+
52+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
53+#if !defined(CFG_NAND_LEGACY)
54+
55+#include <nand.h>
56+#include <s3c2410.h>
57+
58+#define __REGb(x) (*(volatile unsigned char *)(x))
59+#define __REGi(x) (*(volatile unsigned int *)(x))
60+
61+#define NF_BASE 0x4e000000
62+#define NFCONF __REGi(NF_BASE + 0x0)
63+#define NFCMD __REGb(NF_BASE + 0x4)
64+#define NFADDR __REGb(NF_BASE + 0x8)
65+#define NFDATA __REGb(NF_BASE + 0xc)
66+#define NFSTAT __REGb(NF_BASE + 0x10)
67+#define NFECC0 __REGb(NF_BASE + 0x14)
68+#define NFECC1 __REGb(NF_BASE + 0x15)
69+#define NFECC2 __REGb(NF_BASE + 0x16)
70+
71+#define S3C2410_NFCONF_EN (1<<15)
72+#define S3C2410_NFCONF_512BYTE (1<<14)
73+#define S3C2410_NFCONF_4STEP (1<<13)
74+#define S3C2410_NFCONF_INITECC (1<<12)
75+#define S3C2410_NFCONF_nFCE (1<<11)
76+#define S3C2410_NFCONF_TACLS(x) ((x)<<8)
77+#define S3C2410_NFCONF_TWRPH0(x) ((x)<<4)
78+#define S3C2410_NFCONF_TWRPH1(x) ((x)<<0)
79+
80+static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd)
81+{
82+ struct nand_chip *chip = mtd->priv;
83+
84+ DEBUGN("hwcontrol(): 0x%02x: ", cmd);
85+
86+ switch (cmd) {
87+ case NAND_CTL_SETNCE:
88+ NFCONF &= ~S3C2410_NFCONF_nFCE;
89+ DEBUGN("NFCONF=0x%08x\n", NFCONF);
90+ break;
91+ case NAND_CTL_CLRNCE:
92+ NFCONF |= S3C2410_NFCONF_nFCE;
93+ DEBUGN("NFCONF=0x%08x\n", NFCONF);
94+ break;
95+ case NAND_CTL_SETALE:
96+ chip->IO_ADDR_W = NF_BASE + 0x8;
97+ DEBUGN("SETALE\n");
98+ break;
99+ case NAND_CTL_SETCLE:
100+ chip->IO_ADDR_W = NF_BASE + 0x4;
101+ DEBUGN("SETCLE\n");
102+ break;
103+ default:
104+ chip->IO_ADDR_W = NF_BASE + 0xc;
105+ break;
106+ }
107+ return;
108+}
109+
110+static int s3c2410_dev_ready(struct mtd_info *mtd)
111+{
112+ DEBUGN("dev_ready\n");
113+ return (NFSTAT & 0x01);
114+}
115+
116+static void s3c2410_cmdfunc(struct mtd_info *mtd, unsigned cmd,
117+ int column, int page_addr)
118+{
119+ DEBUGN("cmdfunc(): 0x%02x, col=%d, page=%d\n", cmd, column, page_addr);
120+
121+ switch (cmd) {
122+ case NAND_CMD_READ0:
123+ case NAND_CMD_READ1:
124+ case NAND_CMD_READOOB:
125+ NFCMD = cmd;
126+ NFADDR = column & 0xff;
127+ NFADDR = page_addr & 0xff;
128+ NFADDR = (page_addr >> 8) & 0xff;
129+ NFADDR = (page_addr >> 16) & 0xff;
130+ break;
131+ case NAND_CMD_READID:
132+ NFCMD = cmd;
133+ NFADDR = 0;
134+ break;
135+ case NAND_CMD_PAGEPROG:
136+ NFCMD = cmd;
137+ printf("PAGEPROG not implemented\n");
138+ break;
139+ case NAND_CMD_ERASE1:
140+ NFCMD = cmd;
141+ NFADDR = page_addr & 0xff;
142+ NFADDR = (page_addr >> 8) & 0xff;
143+ NFADDR = (page_addr >> 16) & 0xff;
144+ break;
145+ case NAND_CMD_ERASE2:
146+ NFCMD = cmd;
147+ break;
148+ case NAND_CMD_SEQIN:
149+ printf("SEQIN not implemented\n");
150+ break;
151+ case NAND_CMD_STATUS:
152+ NFCMD = cmd;
153+ break;
154+ case NAND_CMD_RESET:
155+ NFCMD = cmd;
156+ break;
157+ default:
158+ break;
159+ }
160+
161+ while (!s3c2410_dev_ready(mtd));
162+}
163+
164+#ifdef CONFIG_S3C2410_NAND_HWECC
165+void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
166+{
167+ DEBUGN("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd ,mode);
168+ NFCONF |= S3C2410_NFCONF_INITECC;
169+}
170+
171+static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
172+{
173+ ecc_code[0] = NFECC0;
174+ ecc_code[1] = NFECC1;
175+ ecc_code[2] = NFECC2;
176+ DEBUGN("s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n", mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
177+
178+ return 0;
179+}
180+
181+int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
182+{
183+ if (read_ecc[0] == calc_ecc[0] &&
184+ read_ecc[1] == calc_ecc[1] &&
185+ read_ecc[2] == calc_ecc[2])
186+ return 0;
187+
188+ printf("s3c2410_nand_correct_data: not implemented\n");
189+ return -1;
190+}
191+#endif
192+
193+int board_nand_init(struct nand_chip *nand)
194+{
195+ u_int32_t cfg;
196+ u_int8_t tacls, twrph0, twrph1;
197+ S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
198+
199+ DEBUGN("board_nand_init()\n");
200+
201+ clk_power->CLKCON |= (1 << 4);
202+
203+ /* initialize hardware */
204+ twrph0 = 3; twrph1 = 0; tacls = 0;
205+
206+ cfg = S3C2410_NFCONF_EN;
207+ cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
208+ cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
209+ cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
210+
211+ NFCONF = cfg;
212+ //NFCONF = 0xf842;
213+
214+ /* initialize nand_chip data structure */
215+ nand->IO_ADDR_R = nand->IO_ADDR_W = 0x4e00000c;
216+
217+ /* read_buf and write_buf are default */
218+ /* read_byte and write_byte are default */
219+
220+ /* hwcontrol always must be implemented */
221+ nand->hwcontrol = s3c2410_hwcontrol;
222+
223+ nand->dev_ready = s3c2410_dev_ready;
224+
225+#ifdef CONFIG_S3C2410_NAND_HWECC
226+ nand->enable_hwecc = s3c2410_nand_enable_hwecc;
227+ nand->calculate_ecc = s3c2410_nand_calculate_ecc;
228+ nand->correct_data = s3c2410_nand_correct_data;
229+ nand->eccmode = NAND_ECC_HW3_512;
230+#else
231+ nand->eccmode = NAND_ECC_SOFT;
232+#endif
233+
234+#ifdef CONFIG_S3C2410_NAND_BBT
235+ nand->options = NAND_USE_FLASH_BBT;
236+#else
237+ nand->options = 0;
238+#endif
239+
240+ DEBUGN("end of nand_init\n");
241+
242+ return 0;
243+}
244+
245+#else
246+ #error "U-Boot legacy NAND support not available for S3C2410"
247+#endif
248+#endif
249Index: u-boot/cpu/arm920t/s3c24x0/nand_read.c
250===================================================================
251--- /dev/null 1970-01-01 00:00:00.000000000 +0000
252+++ u-boot/cpu/arm920t/s3c24x0/nand_read.c 2007-02-28 03:51:24.000000000 +0100
253@@ -0,0 +1,98 @@
254+/*
255+ * nand_read.c: Simple NAND read functions for booting from NAND
256+ *
257+ * This is used by cpu/arm920/start.S assembler code,
258+ * and the board-specific linker script must make sure this
259+ * file is linked within the first 4kB of NAND flash.
260+ *
261+ * Taken from GPLv2 licensed vivi bootloader,
262+ * Copyright (C) 2002 MIZI Research, Inc.
263+ *
264+ * Author: Hwang, Chideok <hwang@mizi.com>
265+ * Date : $Date: 2004/02/04 10:37:37 $
266+ *
267+ * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc.
268+ * Author: Harald Welte <laforge@openmoko.org>
269+ */
270+
271+#include <common.h>
272+
273+#ifdef CONFIG_S3C2410_NAND_BOOT
274+
275+#define __REGb(x) (*(volatile unsigned char *)(x))
276+#define __REGi(x) (*(volatile unsigned int *)(x))
277+#define NF_BASE 0x4e000000
278+#define NFCONF __REGi(NF_BASE + 0x0)
279+#define NFCMD __REGb(NF_BASE + 0x4)
280+#define NFADDR __REGb(NF_BASE + 0x8)
281+#define NFDATA __REGb(NF_BASE + 0xc)
282+#define NFSTAT __REGb(NF_BASE + 0x10)
283+
284+#define BUSY 1
285+inline void wait_idle(void)
286+{
287+ int i;
288+
289+ while (!(NFSTAT & BUSY))
290+ for (i=0; i<10; i++);
291+}
292+
293+#define NAND_SECTOR_SIZE 512
294+#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
295+#define NAND_PAGE_SIZE 0x4000
296+
297+/* low level nand read function */
298+int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
299+{
300+ int i, j;
301+
302+ if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK))
303+ return -1; /* invalid alignment */
304+
305+ /* chip Enable */
306+ NFCONF &= ~0x800;
307+ for (i=0; i<10; i++);
308+
309+ for (i=start_addr; i < (start_addr + size);) {
310+#ifdef CONFIG_S3C2410_NAND_SKIP_BAD
311+ if (start_addr % NAND_PAGE_SIZE == 0) {
312+ unsigned char data;
313+ NFCMD = 0x50;
314+ NFADDR = 517&0xf;
315+ NFADDR = (i >> 9) & 0xff;
316+ NFADDR = (i >> 17) & 0xff;
317+ NFADDR = (i >> 25) & 0xff;
318+ wait_idle();
319+ data = (NFDATA & 0xff);
320+ if (data != 0xff) {
321+ /* Bad block */
322+ i += NAND_PAGE_SIZE;
323+ size += NAND_PAGE_SIZE;
324+ continue;
325+ }
326+ }
327+#endif
328+ /* READ0 */
329+ NFCMD = 0;
330+
331+ /* Write Address */
332+ NFADDR = i & 0xff;
333+ NFADDR = (i >> 9) & 0xff;
334+ NFADDR = (i >> 17) & 0xff;
335+ NFADDR = (i >> 25) & 0xff;
336+
337+ wait_idle();
338+
339+ for (j=0; j < NAND_SECTOR_SIZE; j++, i++) {
340+ *buf = (NFDATA & 0xff);
341+ buf++;
342+ }
343+ }
344+
345+ /* chip Disable */
346+ NFCONF |= 0x800; /* chip disable */
347+
348+ return 0;
349+}
350+
351+#endif /* CONFIG_S3C2410_NAND_BOOT */
352Index: u-boot/cpu/arm920t/start.S
353===================================================================
354--- u-boot.orig/cpu/arm920t/start.S 2007-02-28 03:47:44.000000000 +0100
355+++ u-boot/cpu/arm920t/start.S 2007-03-01 14:29:22.000000000 +0100
356@@ -5,6 +5,10 @@
357 * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
358 * Copyright (c) 2002 Gary Jennejohn <gj@denx.de>
359 *
360+ * S3C2410 NAND portions
361+ * Copyright (c) 2001 MIZI Research, Inc.
362+ * Copyright (c) 2006 OpenMoko, Inc. (Harald Welte <laforge@openmmoko.org>
363+ *
364 * See file CREDITS for list of people who contributed to this
365 * project.
366 *
367@@ -27,6 +31,7 @@
368
369 #include <config.h>
370 #include <version.h>
371+#include <s3c2410.h>
372
373
374 /*
375@@ -161,6 +166,7 @@
376 #endif
377
378 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
379+#ifndef CONFIG_S3C2410_NAND_BOOT
380 relocate: /* relocate U-Boot to RAM */
381 adr r0, _start /* r0 <- current position of code */
382 ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
383@@ -177,6 +183,93 @@
384 stmia r1!, {r3-r10} /* copy to target address [r1] */
385 cmp r0, r2 /* until source end addreee [r2] */
386 ble copy_loop
387+#else /* NAND_BOOT */
388+relocate:
389+copy_myself:
390+ /* mov r10, lr */
391+
392+ @ reset NAND
393+ mov r1, #S3C2410_NAND_BASE
394+ ldr r2, =0xf842 @ initial value enable tacls=3,rph0=6,rph1=0
395+ str r2, [r1, #oNFCONF]
396+ ldr r2, [r1, #oNFCONF]
397+ bic r2, r2, #0x800 @ enable chip
398+ str r2, [r1, #oNFCONF]
399+ mov r2, #0xff @ RESET command
400+ strb r2, [r1, #oNFCMD]
401+ mov r3, #0 @ wait
402+1: add r3, r3, #0x1
403+ cmp r3, #0xa
404+ blt 1b
405+2: ldr r2, [r1, #oNFSTAT] @ wait ready
406+ tst r2, #0x1
407+ beq 2b
408+ ldr r2, [r1, #oNFCONF]
409+ orr r2, r2, #0x800 @ disable chip
410+ str r2, [r1, #oNFCONF]
411+
412+#if 0
413+ @ get ready to call C functions (for nand_read())
414+ ldr sp, DW_STACK_START @ setup stack pointer
415+ mov fp, #0 @ no previous frame, so fp=0
416+#else
417+ ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
418+ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
419+ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
420+#ifdef CONFIG_USE_IRQ
421+ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
422+#endif
423+ sub sp, r0, #12 /* leave 3 words for abort-stack */
424+#endif
425+
426+ @ copy u-boot to RAM
427+ ldr r0, _TEXT_BASE
428+ mov r1, #0x0
429+ mov r2, #CFG_UBOOT_SIZE
430+ bl nand_read_ll
431+
432+ tst r0, #0x0
433+ beq ok_nand_read
434+#ifdef CONFIG_DEBUG_LL
435+bad_nand_read:
436+ ldr r0, STR_FAIL
437+ ldr r1, SerBase
438+ bl PrintWord
439+1: b 1b @ infinite loop
440+#endif
441+
442+ok_nand_read:
443+#ifdef CONFIG_DEBUG_LL
444+ ldr r0, STR_OK
445+ ldr r1, SerBase
446+ bl PrintWord
447+#endif
448+
449+ @ verify
450+ mov r0, #0
451+ @ldr r1, =0x33f00000
452+ ldr r1, _TEXT_BASE
453+ mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes
454+go_next:
455+ ldr r3, [r0], #4
456+ ldr r4, [r1], #4
457+ teq r3, r4
458+ bne notmatch
459+ subs r2, r2, #4
460+ beq done_nand_read
461+ bne go_next
462+notmatch:
463+#ifdef CONFIG_DEBUG_LL
464+ sub r0, r0, #4
465+ ldr r1, SerBase
466+ bl PrintHexWord
467+ ldr r0, STR_FAIL
468+ ldr r1, SerBase
469+ bl PrintWord
470+#endif
471+1: b 1b
472+done_nand_read:
473+#endif /* NAND_BOOT */
474 #endif /* CONFIG_SKIP_RELOCATE_UBOOT */
475
476 /* Set up the stack */
477Index: u-boot/include/s3c2410.h
478===================================================================
479--- u-boot.orig/include/s3c2410.h 2007-02-28 03:51:24.000000000 +0100
480+++ u-boot/include/s3c2410.h 2007-03-01 14:29:22.000000000 +0100
481@@ -38,12 +38,6 @@
482 #define S3C2410_ECCSIZE 512
483 #define S3C2410_ECCBYTES 3
484
485-typedef enum {
486- S3C24X0_UART0,
487- S3C24X0_UART1,
488- S3C24X0_UART2
489-} S3C24X0_UARTS_NR;
490-
491 /* S3C2410 device base addresses */
492 #define S3C24X0_MEMCTL_BASE 0x48000000
493 #define S3C24X0_USB_HOST_BASE 0x49000000
494@@ -65,9 +59,23 @@
495 #define S3C2410_SDI_BASE 0x5A000000
496
497
498+#define oNFCONF 0x00
499+#define oNFCMD 0x04
500+#define oNFADDR 0x08
501+#define oNFDATA 0x0C
502+#define oNFSTAT 0x10
503+#define oNFECC 0x14
504+
505+#ifndef __ASSEMBLER__
506+
507 /* include common stuff */
508 #include <s3c24x0.h>
509
510+typedef enum {
511+ S3C24X0_UART0,
512+ S3C24X0_UART1,
513+ S3C24X0_UART2
514+} S3C24X0_UARTS_NR;
515
516 static inline S3C24X0_MEMCTL * S3C24X0_GetBase_MEMCTL(void)
517 {
518@@ -142,6 +150,7 @@
519 return (S3C2410_SDI * const)S3C2410_SDI_BASE;
520 }
521
522+#endif
523
524 /* ISR */
525 #define pISR_RESET (*(unsigned *)(_ISR_STARTADDRESS+0x0))