public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/4] Voipac PXA270 OneNAND SPL
@ 2011-10-31 13:23 Marek Vasut
  2011-10-31 13:23 ` [U-Boot] [PATCH 1/4] PXA: Drop Voipac PXA270 OneNAND IPL Marek Vasut
                   ` (3 more replies)
  0 siblings, 4 replies; 38+ messages in thread
From: Marek Vasut @ 2011-10-31 13:23 UTC (permalink / raw)
  To: u-boot

Convert OneNAND IPL to SPL framework and make Voipac PXA270 board use it.

This series triggers some checkpatch warnings:
* Warnings in start.S due to length of line. Since I reused the start.S from
  other CPU (arm1136), I'd rather investigate if it'd be possible to create one
  common start.S for armv5?
* Warnings due to used externs. pxa_dram_init() will be cleaned up in a
  subsequent series in all boards.

Marek Vasut (4):
  PXA: Drop Voipac PXA270 OneNAND IPL
  PXA: Rework start.S to be closer to other ARMs
  OneNAND: Add simple OneNAND SPL
  PXA: Adapt Voipac PXA270 to OneNAND SPL

 arch/arm/cpu/pxa/cpu.c                       |   16 +
 arch/arm/cpu/pxa/start.S                     |  382 +++++++++-----------------
 board/vpac270/Makefile                       |    6 +
 board/vpac270/onenand.c                      |  136 +++++++++
 board/vpac270/vpac270.c                      |    2 +
 drivers/mtd/onenand/Makefile                 |    4 +
 drivers/mtd/onenand/onenand_spl.c            |  130 +++++++++
 include/configs/vpac270.h                    |   25 ++-
 include/onenand_uboot.h                      |   18 ++
 onenand_ipl/board/vpac270/Makefile           |   79 ------
 onenand_ipl/board/vpac270/config.mk          |    1 -
 onenand_ipl/board/vpac270/u-boot.onenand.lds |   51 ----
 onenand_ipl/board/vpac270/vpac270.c          |   42 ---
 spl/Makefile                                 |    1 +
 14 files changed, 469 insertions(+), 424 deletions(-)
 create mode 100644 board/vpac270/onenand.c
 create mode 100644 drivers/mtd/onenand/onenand_spl.c
 delete mode 100644 onenand_ipl/board/vpac270/Makefile
 delete mode 100644 onenand_ipl/board/vpac270/config.mk
 delete mode 100644 onenand_ipl/board/vpac270/u-boot.onenand.lds
 delete mode 100644 onenand_ipl/board/vpac270/vpac270.c

Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>

-- 
1.7.6.3

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 1/4] PXA: Drop Voipac PXA270 OneNAND IPL
  2011-10-31 13:23 [U-Boot] [PATCH 0/4] Voipac PXA270 OneNAND SPL Marek Vasut
@ 2011-10-31 13:23 ` Marek Vasut
  2011-10-31 13:23 ` [U-Boot] [PATCH 2/4] PXA: Rework start.S to be closer to other ARMs Marek Vasut
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 38+ messages in thread
From: Marek Vasut @ 2011-10-31 13:23 UTC (permalink / raw)
  To: u-boot

This OneNAND IPL will be replaced by OneNAND SPL.

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
---
 onenand_ipl/board/vpac270/Makefile           |   79 --------------------------
 onenand_ipl/board/vpac270/config.mk          |    1 -
 onenand_ipl/board/vpac270/u-boot.onenand.lds |   51 -----------------
 onenand_ipl/board/vpac270/vpac270.c          |   42 --------------
 4 files changed, 0 insertions(+), 173 deletions(-)
 delete mode 100644 onenand_ipl/board/vpac270/Makefile
 delete mode 100644 onenand_ipl/board/vpac270/config.mk
 delete mode 100644 onenand_ipl/board/vpac270/u-boot.onenand.lds
 delete mode 100644 onenand_ipl/board/vpac270/vpac270.c

diff --git a/onenand_ipl/board/vpac270/Makefile b/onenand_ipl/board/vpac270/Makefile
deleted file mode 100644
index f850ddd..0000000
--- a/onenand_ipl/board/vpac270/Makefile
+++ /dev/null
@@ -1,79 +0,0 @@
-
-include $(TOPDIR)/config.mk
-include $(TOPDIR)/board/$(BOARDDIR)/config.mk
-
-LDSCRIPT= $(TOPDIR)/onenand_ipl/board/$(BOARDDIR)/u-boot.onenand.lds
-LDFLAGS	= -Bstatic -T $(onenandobj)u-boot.lds -Ttext $(CONFIG_SYS_TEXT_BASE) $(PLATFORM_LDFLAGS)
-AFLAGS	+= -DCONFIG_SPL_BUILD -DCONFIG_ONENAND_IPL
-CFLAGS	+= -DCONFIG_SPL_BUILD -DCONFIG_ONENAND_IPL
-OBJCFLAGS += --gap-fill=0x00
-
-SOBJS	+= start.o
-COBJS	:= vpac270.o
-COBJS	+= onenand_read.o
-COBJS	+= onenand_boot.o
-
-SRCS	:= $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
-OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
-__OBJS	:= $(SOBJS) $(COBJS)
-LNDIR	:= $(OBJTREE)/onenand_ipl/board/$(BOARDDIR)
-
-onenandobj	:= $(OBJTREE)/onenand_ipl/
-
-ALL	= $(onenandobj)onenand-ipl $(onenandobj)onenand-ipl.bin $(onenandobj)onenand-ipl-2k.bin
-
-all:	$(obj).depend $(ALL)
-
-$(onenandobj)onenand-ipl-2k.bin:	$(onenandobj)onenand-ipl
-	$(OBJCOPY) ${OBJCFLAGS} --pad-to=0x0800 -O binary $< $@
-
-$(onenandobj)onenand-ipl.bin:	$(onenandobj)onenand-ipl
-	$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
-
-$(onenandobj)onenand-ipl:	$(OBJS) $(onenandobj)u-boot.lds
-	cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
-		-Map $@.map -o $@
-
-$(onenandobj)u-boot.lds:	$(LDSCRIPT)
-	$(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@
-
-# create symbolic links from common files
-
-# from cpu directory
-$(obj)start.S:
-	@rm -f $@
-	ln -s $(SRCTREE)/$(CPUDIR)/start.S $@
-
-# from onenand_ipl directory
-$(obj)onenand_ipl.h:
-	@rm -f $@
-	ln -s $(SRCTREE)/onenand_ipl/onenand_ipl.h $@
-
-$(obj)onenand_boot.c:	$(obj)onenand_ipl.h
-	@rm -f $@
-	ln -s $(SRCTREE)/onenand_ipl/onenand_boot.c $@
-
-$(obj)onenand_read.c:	$(obj)onenand_ipl.h
-	@rm -f $@
-	ln -s $(SRCTREE)/onenand_ipl/onenand_read.c $@
-
-ifneq ($(OBJTREE), $(SRCTREE))
-$(obj)vpac270.c:
-	@rm -f $@
-	ln -s $(SRCTREE)/onenand_ipl/board/$(BOARDDIR)/vpac270.c $@
-endif
-
-#########################################################################
-
-$(obj)%.o:	$(obj)%.S
-	$(CC) $(AFLAGS) -c -o $@ $<
-
-$(obj)%.o:	$(obj)$.c
-	$(CC) $(CFLAGS) -c -o $@ $<
-
-# defines $(obj).depend target
-include $(SRCTREE)/rules.mk
-
-sinclude $(obj).depend
-
-#########################################################################
diff --git a/onenand_ipl/board/vpac270/config.mk b/onenand_ipl/board/vpac270/config.mk
deleted file mode 100644
index 752836d..0000000
--- a/onenand_ipl/board/vpac270/config.mk
+++ /dev/null
@@ -1 +0,0 @@
-CONFIG_SYS_TEXT_BASE = 0x5c03fc00
diff --git a/onenand_ipl/board/vpac270/u-boot.onenand.lds b/onenand_ipl/board/vpac270/u-boot.onenand.lds
deleted file mode 100644
index b5b2646..0000000
--- a/onenand_ipl/board/vpac270/u-boot.onenand.lds
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * (C) Copyright 2000
- * Wolfgang Denk, DENX Software Engineering, wd at 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      :
-	{
-	  start.o	(.text)
-	  *(.text)
-	}
-
-	. = ALIGN(4);
-	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
-	. = ALIGN(4);
-	.data : { *(.data) }
-
-	. = ALIGN(4);
-	.got : { *(.got) }
-
-	. = ALIGN(4);
-	__bss_start = .;
-	.bss : { *(.bss) . = ALIGN(4); }
-	__bss_end__ = .;
-}
diff --git a/onenand_ipl/board/vpac270/vpac270.c b/onenand_ipl/board/vpac270/vpac270.c
deleted file mode 100644
index a1eb331..0000000
--- a/onenand_ipl/board/vpac270/vpac270.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * (C) Copyright 2004
- * Robert Whaley, Applied Data Systems, Inc. rwhaley at applieddata.net
- *
- * (C) Copyright 2002
- * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.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
- */
-
-#include <common.h>
-#include <asm/arch/hardware.h>
-
-int board_init (void)
-{
-	return 0;
-}
-
-int s_init(int skip)
-{
-	return 0;
-}
-- 
1.7.6.3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 2/4] PXA: Rework start.S to be closer to other ARMs
  2011-10-31 13:23 [U-Boot] [PATCH 0/4] Voipac PXA270 OneNAND SPL Marek Vasut
  2011-10-31 13:23 ` [U-Boot] [PATCH 1/4] PXA: Drop Voipac PXA270 OneNAND IPL Marek Vasut
@ 2011-10-31 13:23 ` Marek Vasut
  2011-11-01 22:53   ` [U-Boot] [PATCH 2/4 V2] " Marek Vasut
  2011-11-02  9:01   ` [U-Boot] [PATCH 2/4] " Stefan Herbrechtsmeier
  2011-10-31 13:23 ` [U-Boot] [PATCH 3/4] OneNAND: Add simple OneNAND SPL Marek Vasut
  2011-10-31 13:23 ` [U-Boot] [PATCH 4/4] PXA: Adapt Voipac PXA270 to " Marek Vasut
  3 siblings, 2 replies; 38+ messages in thread
From: Marek Vasut @ 2011-10-31 13:23 UTC (permalink / raw)
  To: u-boot

The start.S on PXA was very obscure. This reworks it back to be close to arm1136
start.S and others.

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
---
 arch/arm/cpu/pxa/cpu.c   |   16 ++
 arch/arm/cpu/pxa/start.S |  382 ++++++++++++++++-----------------------------
 2 files changed, 152 insertions(+), 246 deletions(-)

diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c
index df351c7..c48b2ef 100644
--- a/arch/arm/cpu/pxa/cpu.c
+++ b/arch/arm/cpu/pxa/cpu.c
@@ -328,3 +328,19 @@ void i2c_clk_enable(void)
 	writel(readl(CKEN) | CKEN14_I2C, CKEN);
 #endif
 }
+
+void reset_cpu(ulong ignored) __attribute__((noreturn));
+
+void reset_cpu(ulong ignored)
+{
+	uint32_t tmp;
+
+	setbits_le32(OWER, OWER_WME);
+
+	tmp = readl(OSCR);
+	tmp += 0x1000;
+	writel(tmp, OSMR3);
+
+	for (;;)
+		;
+}
diff --git a/arch/arm/cpu/pxa/start.S b/arch/arm/cpu/pxa/start.S
index 6191a73..46f7ac0 100644
--- a/arch/arm/cpu/pxa/start.S
+++ b/arch/arm/cpu/pxa/start.S
@@ -1,14 +1,20 @@
 /*
- *  armboot - Startup Code for XScale
+ *  armboot - Startup Code for XScale CPU-core
  *
  *  Copyright (C) 1998	Dan Malek <dmalek@jlc.net>
  *  Copyright (C) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
  *  Copyright (C) 2000	Wolfgang Denk <wd@denx.de>
  *  Copyright (C) 2001	Alex Zuepke <azu@sysgo.de>
+ *  Copyright (C) 2001	Marius Groger <mag@sysgo.de>
+ *  Copyright (C) 2002	Alex Zupke <azu@sysgo.de>
+ *  Copyright (C) 2002	Gary Jennejohn <garyj@denx.de>
  *  Copyright (C) 2002	Kyle Harris <kharris@nexus-tech.net>
- *  Copyright (C) 2003	Robert Schwebel <r.schwebel@pengutronix.de>
  *  Copyright (C) 2003	Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de>
- *  Copyright (c) 2010	Marek Vasut <marek.vasut@gmail.com>
+ *  Copyright (C) 2003	Kshitij <kshitij@ti.com>
+ *  Copyright (C) 2003	Richard Woodruff <r-woodruff2@ti.com>
+ *  Copyright (C) 2003	Robert Schwebel <r.schwebel@pengutronix.de>
+ *  Copyright (C) 2004	Texas Instruments <r-woodruff2@ti.com>
+ *  Copyright (C) 2010	Marek Vasut <marek.vasut@gmail.com>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -32,15 +38,6 @@
 #include <asm-offsets.h>
 #include <config.h>
 #include <version.h>
-#include <asm/arch/pxa-regs.h>
-
-/* takes care the CP15 update has taken place */
-.macro CPWAIT reg
-mrc  p15,0,\reg,c2,c0,0
-mov  \reg,\reg
-sub  pc,pc,#4
-.endm
-
 .globl _start
 _start: b	reset
 #ifdef CONFIG_SPL_BUILD
@@ -77,26 +74,38 @@ _data_abort:		.word data_abort
 _not_used:		.word not_used
 _irq:			.word irq
 _fiq:			.word fiq
+_pad:			.word 0x12345678 /* now 16*4=64 */
 #endif	/* CONFIG_SPL_BUILD */
+.global _end_vect
+_end_vect:
 
 	.balignl 16,0xdeadbeef
-
-
 /*
+ *************************************************************************
+ *
  * Startup Code (reset vector)
  *
- * do important init only if we don't start from RAM!
- * - relocate armboot to RAM
- * - setup stack
- * - jump to second stage
+ * do important init only if we don't start from memory!
+ * setup Memory and board specific bits prior to relocation.
+ * relocate armboot to ram
+ * setup stack
+ *
+ *************************************************************************
  */
 
 .globl _TEXT_BASE
 _TEXT_BASE:
+#ifdef	CONFIG_SPL_BUILD
+	.word	CONFIG_SPL_TEXT_BASE
+#else
 	.word	CONFIG_SYS_TEXT_BASE
+#endif
 
 /*
  * These are defined in the board-specific linker script.
+ * Subtracting _start from them lets the linker put their
+ * relative position in the executable instead of leaving
+ * them null.
  */
 .globl _bss_start_ofs
 _bss_start_ofs:
@@ -120,9 +129,8 @@ IRQ_STACK_START:
 .globl FIQ_STACK_START
 FIQ_STACK_START:
 	.word 0x0badc0de
-#endif /* CONFIG_USE_IRQ */
+#endif
 
-#ifndef CONFIG_SPL_BUILD
 /* IRQ stack memory (calculated at run-time) + 8 bytes */
 .globl IRQ_STACK_START_IN
 IRQ_STACK_START_IN:
@@ -141,91 +149,15 @@ reset:
 	orr	r0,r0,#0xd3
 	msr	cpsr,r0
 
-	/*
-	 * Enable MMU to use DCache as DRAM
-	 */
-	/* Domain access -- enable for all CPs */
-	ldr	r0, =0x0000ffff
-	mcr	p15, 0, r0, c3, c0, 0
-
-	/* Point TTBR to MMU table */
-	ldr	r0, =mmu_table
-	adr	r2, _start
-	orr	r0, r2
-	mcr	p15, 0, r0, c2, c0, 0
-
-/* !!! Hereby, check if the code is running from SRAM !!! */
-/* If the code is running from SRAM, alias SRAM to 0x0 to simulate NOR. The code
- * is linked to 0x0 too, so this makes things easier. */
-	cmp	r2, #0x5c000000
-
-	ldreq	r1, [r0]
-	orreq	r1, r2
-	streq	r1, [r0]
-
-	/* Kick in MMU, ICache, DCache, BTB */
-	mrc	p15, 0, r0, c1, c0, 0
-	bic	r0, #0x1b00
-	bic	r0, #0x0087
-	orr	r0, #0x1800
-	orr	r0, #0x0005
-	mcr	p15, 0, r0, c1, c0, 0
-	CPWAIT	r0
-
-	/* Unlock Icache, Dcache */
-	mcr	p15, 0, r0, c9, c1, 1
-	mcr	p15, 0, r0, c9, c2, 1
-
-	/* Flush Icache, Dcache, BTB */
-	mcr	p15, 0, r0, c7, c7, 0
-
-	/* Unlock I-TLB, D-TLB */
-	mcr	p15, 0, r0, c10, c4, 1
-	mcr	p15, 0, r0, c10, c8, 1
-
-	/* Flush TLB */
-	mcr	p15, 0, r0, c8, c7, 0
-	/* Allocate 4096 bytes of Dcache as RAM */
-
-	/* Drain pending loads and stores */
-	mcr	p15, 0, r0, c7, c10, 4
-
-	mov	r4, #0x00
-	mov	r5, #0x00
-	mov	r2, #0x01
-	mcr	p15, 0, r0, c9, c2, 0
-	CPWAIT	r0
-
-	/* 128 lines reserved (128 x 32bytes = 4096 bytes total) */
-	mov	r0, #128
-	mov	r1, #0xa0000000
-alloc:
-	mcr	p15, 0, r1, c7, c2, 5
-	/* Drain pending loads and stores */
-	mcr	p15, 0, r0, c7, c10, 4
-	strd	r4, [r1], #8
-	strd	r4, [r1], #8
-	strd	r4, [r1], #8
-	strd	r4, [r1], #8
-	subs	r0, #0x01
-	bne	alloc
-	/* Drain pending loads and stores */
-	mcr	p15, 0, r0, c7, c10, 4
-	mov	r2, #0x00
-	mcr	p15, 0, r2, c9, c2, 0
-	CPWAIT	r0
-
-	/* Jump to 0x0 ( + offset) if running from SRAM */
-	adr	r0, zerojmp
-	bic	r0, #0x5c000000
-	mov	pc, r0
-zerojmp:
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+	bl  cpu_init_crit
+#endif
 
 /* Set stackpointer in internal RAM to call board_init_f */
 call_board_init_f:
 	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
 	bic	sp, sp, #7 /* 8-byte alignment for ABI compliance */
-	ldr	r0,=0x00000000
+	ldr	r0, =0x00000000
 	bl	board_init_f
 
 /*------------------------------------------------------------------------------*/
@@ -254,13 +186,11 @@ stack_setup:
 	ldr	r3, _bss_start_ofs
 	add	r2, r0, r3		/* r2 <- source end address	    */
 
-	stmfd sp!, {r0-r12}
 copy_loop:
-	ldmia	r0!, {r3-r5, r7-r11}	/* copy from source address [r0]    */
-	stmia	r1!, {r3-r5, r7-r11}	/* copy to   target address [r1]    */
+	ldmia	r0!, {r9-r10}		/* copy from source address [r0]    */
+	stmia	r1!, {r9-r10}		/* copy to   target address [r1]    */
 	cmp	r0, r2			/* until source end address [r2]    */
 	blo	copy_loop
-	ldmfd sp!, {r0-r12}
 
 #ifndef CONFIG_SPL_BUILD
 	/*
@@ -275,13 +205,13 @@ copy_loop:
 	ldr	r3, _rel_dyn_end_ofs	/* r3 <- rel dyn end ofs */
 	add	r3, r3, r0		/* r3 <- rel dyn end in FLASH */
 fixloop:
-	ldr	r0, [r2]	/* r0 <- location to fix up, IN FLASH! */
-	add	r0, r9		/* r0 <- location to fix up in RAM */
+	ldr	r0, [r2]		/* r0 <- location to fix up, IN FLASH! */
+	add	r0, r0, r9		/* r0 <- location to fix up in RAM */
 	ldr	r1, [r2, #4]
 	and	r7, r1, #0xff
-	cmp	r7, #23		/* relative fixup? */
+	cmp	r7, #23			/* relative fixup? */
 	beq	fixrel
-	cmp	r7, #2		/* absolute fixup? */
+	cmp	r7, #2			/* absolute fixup? */
 	beq	fixabs
 	/* ignore unknown type of fixup */
 	b	fixnext
@@ -298,10 +228,10 @@ fixrel:
 	add	r1, r1, r9
 fixnext:
 	str	r1, [r0]
-	add	r2, r2, #8	/* each rel.dyn entry is 8 bytes */
+	add	r2, r2, #8		/* each rel.dyn entry is 8 bytes */
 	cmp	r2, r3
 	blo	fixloop
-#endif	/* #ifndef CONFIG_SPL_BUILD */
+#endif
 
 clear_bss:
 #ifndef CONFIG_SPL_BUILD
@@ -322,15 +252,16 @@ clbss_l:str	r2, [r0]		/* clear loop...		    */
  * We are done. Do not return, instead branch to second part of board
  * initialization, now running from RAM.
  */
-#ifdef CONFIG_ONENAND_IPL
-	ldr     r0, _start_oneboot_ofs
+#ifdef CONFIG_ONENAND_SPL
+	ldr     r0, _onenand_boot_ofs
 	mov	pc, r0
 
-_start_oneboot_ofs
-	: .word start_oneboot
+_onenand_boot_ofs:
+	.word onenand_boot
 #else
+jump_2_ram:
 	ldr	r0, _board_init_r_ofs
-	adr	r1, _start
+	ldr     r1, _TEXT_BASE
 	add	lr, r0, r1
 	add	lr, lr, r9
 	/* setup parameters for board_init_r */
@@ -341,7 +272,7 @@ _start_oneboot_ofs
 
 _board_init_r_ofs:
 	.word board_init_r - _start
-#endif	/* CONFIG_ONENAND_IPL */
+#endif
 
 _rel_dyn_start_ofs:
 	.word __rel_dyn_start - _start
@@ -350,42 +281,49 @@ _rel_dyn_end_ofs:
 _dynsym_start_ofs:
 	.word __dynsym_start - _start
 
-#else /* CONFIG_SPL_BUILD */
-
-/****************************************************************************/
-/*									    */
-/* the actual reset code for OneNAND IPL				    */
-/*									    */
-/****************************************************************************/
-
-#ifndef	CONFIG_PXA27X
-#error OneNAND IPL is not supported on PXA25x and 26x due to lack of SRAM
-#endif
-
-reset:
-	/* Set CPU to SVC32 mode */
-	mrs	r0,cpsr
-	bic	r0,r0,#0x1f
-	orr	r0,r0,#0x13
-	msr	cpsr,r0
-
-	/* Point stack@the end of SRAM and leave 32 words for abort-stack */
-	ldr	sp, =0x5c03ff80
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+cpu_init_crit:
+	/*
+	 * flush v4 I/D caches
+	 */
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7, 0	/* Invalidate I+D+BTB caches */
+	mcr	p15, 0, r0, c8, c7, 0	/* Invalidate Unified TLB */
 
-	/* Start OneNAND IPL */
-	ldr	pc, =start_oneboot
+	/*
+	 * disable MMU stuff and caches
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS)
+	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM)
+	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align
+	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache
+	mcr	p15, 0, r0, c1, c0, 0
 
-#endif /* CONFIG_SPL_BUILD */
+	mov	pc, lr		/* back to my caller */
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
 
 #ifndef CONFIG_SPL_BUILD
-/****************************************************************************/
-/*									    */
-/* Interrupt handling							    */
-/*									    */
-/****************************************************************************/
-
-/* IRQ stack frame							    */
-
+/*
+ *************************************************************************
+ *
+ * Interrupt handling
+ *
+ *************************************************************************
+ */
+@
+@ IRQ stack frame.
+@
 #define S_FRAME_SIZE	72
 
 #define S_OLD_R0	68
@@ -409,37 +347,36 @@ reset:
 #define S_R0		0
 
 #define MODE_SVC 0x13
+#define I_BIT	 0x80
 
-	/* use bad_save_user_regs for abort/prefetch/undef/swi ...	    */
+/*
+ * use bad_save_user_regs for abort/prefetch/undef/swi ...
+ * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
+ */
 
 	.macro	bad_save_user_regs
-	sub	sp, sp, #S_FRAME_SIZE
-	stmia	sp, {r0 - r12}			/* Calling r0-r12	    */
-	add	r8, sp, #S_PC
+	sub	sp, sp, #S_FRAME_SIZE		@ carve out a frame on current user stack
+	stmia	sp, {r0 - r12}			@ Save user registers (now in svc mode) r0-r12
 
-	ldr	r2, IRQ_STACK_START_IN
-	ldmia	r2, {r2 - r4}			/* get pc, cpsr, old_r0	    */
-	add	r0, sp, #S_FRAME_SIZE		/* restore sp_SVC	    */
+	ldr	r2, IRQ_STACK_START_IN		@ set base 2 words into abort stack
+	ldmia	r2, {r2 - r3}			@ get values for "aborted" pc and cpsr (into parm regs)
+	add	r0, sp, #S_FRAME_SIZE		@ grab pointer to old stack
 
 	add	r5, sp, #S_SP
 	mov	r1, lr
-	stmia	r5, {r0 - r4}			/* save sp_SVC, lr_SVC, pc, cpsr, old_r */
-	mov	r0, sp
+	stmia	r5, {r0 - r3}			@ save sp_SVC, lr_SVC, pc, cpsr
+	mov	r0, sp				@ save current stack into r0 (param register)
 	.endm
 
-
-	/* use irq_save_user_regs / irq_restore_user_regs for		     */
-	/* IRQ/FIQ handling						     */
-
 	.macro	irq_save_user_regs
 	sub	sp, sp, #S_FRAME_SIZE
-	stmia	sp, {r0 - r12}			/* Calling r0-r12	     */
-	add	r8, sp, #S_PC
-	stmdb	r8, {sp, lr}^			/* Calling SP, LR	     */
-	str	lr, [r8, #0]			/* Save calling PC	     */
+	stmia	sp, {r0 - r12}			@ Calling r0-r12
+	add	r8, sp, #S_PC			@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
+	stmdb	r8, {sp, lr}^			@ Calling SP, LR
+	str	lr, [r8, #0]			@ Save calling PC
 	mrs	r6, spsr
-	str	r6, [r8, #4]			/* Save CPSR		     */
-	str	r0, [r8, #8]			/* Save OLD_R0		     */
+	str	r6, [r8, #4]			@ Save CPSR
+	str	r0, [r8, #8]			@ Save OLD_R0
 	mov	r0, sp
 	.endm
 
@@ -452,16 +389,28 @@ reset:
 	.endm
 
 	.macro get_bad_stack
-	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
+	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack (enter in banked mode)
 
-	str	lr, [r13]			@ save caller lr / spsr
-	mrs	lr, spsr
-	str	lr, [r13, #4]
+	str	lr, [r13]			@ save caller lr in position 0 of saved stack
+	mrs	lr, spsr			@ get the spsr
+	str	lr, [r13, #4]			@ save spsr in position 1 of saved stack
 
 	mov	r13, #MODE_SVC			@ prepare SVC-Mode
-	msr	spsr_c, r13
-	mov	lr, pc
-	movs	pc, lr
+	@ msr	spsr_c, r13
+	msr	spsr, r13			@ switch modes, make sure moves will execute
+	mov	lr, pc				@ capture return pc
+	movs	pc, lr				@ jump to next instruction & switch modes.
+	.endm
+
+	.macro get_bad_stack_swi
+	sub	r13, r13, #4			@ space on current stack for scratch reg.
+	str	r0, [r13]			@ save R0's value.
+	ldr	r0, IRQ_STACK_START_IN		@ get data regions start
+	str	lr, [r0]			@ save caller lr in position 0 of saved stack
+	mrs	r0, spsr			@ get the spsr
+	str	lr, [r0, #4]			@ save spsr in position 1 of saved stack
+	ldr	r0, [r13]			@ restore r0
+	add	r13, r13, #4			@ pop stack entry
 	.endm
 
 	.macro get_irq_stack			@ setup IRQ stack
@@ -471,21 +420,17 @@ reset:
 	.macro get_fiq_stack			@ setup FIQ stack
 	ldr	sp, FIQ_STACK_START
 	.endm
-#endif	/* CONFIG_SPL_BUILD
-
-
-/****************************************************************************/
-/*									    */
-/* exception handlers							    */
-/*									    */
-/****************************************************************************/
+#endif	/* CONFIG_SPL_BUILD */
 
+/*
+ * exception handlers
+ */
 #ifdef CONFIG_SPL_BUILD
 	.align	5
 do_hang:
-	ldr	sp, _TEXT_BASE			/* use 32 words abort stack */
+	ldr	sp, _TEXT_BASE			/* use 32 words about stack */
 	bl	hang				/* hang and never return */
-#else
+#else	/* !CONFIG_SPL_BUILD */
 	.align	5
 undefined_instruction:
 	get_bad_stack
@@ -494,7 +439,7 @@ undefined_instruction:
 
 	.align	5
 software_interrupt:
-	get_bad_stack
+	get_bad_stack_swi
 	bad_save_user_regs
 	bl	do_software_interrupt
 
@@ -528,11 +473,12 @@ irq:
 	.align	5
 fiq:
 	get_fiq_stack
-	irq_save_user_regs		/* someone ought to write a more    */
-	bl	do_fiq			/* effiction fiq_save_user_regs	    */
+	/* someone ought to write a more effiction fiq_save_user_regs */
+	irq_save_user_regs
+	bl	do_fiq
 	irq_restore_user_regs
 
-#else /* !CONFIG_USE_IRQ */
+#else
 
 	.align	5
 irq:
@@ -545,63 +491,7 @@ fiq:
 	get_bad_stack
 	bad_save_user_regs
 	bl	do_fiq
-#endif	/* CONFIG_SPL_BUILD */
-#endif /* CONFIG_USE_IRQ */
-
-/****************************************************************************/
-/*									    */
-/* Reset function: the PXA250 doesn't have a reset function, so we have to  */
-/* perform a watchdog timeout for a soft reset.				    */
-/*									    */
-/****************************************************************************/
-/* Operating System Timer */
-.align	5
-.globl reset_cpu
-
-	/* FIXME: this code is PXA250 specific. How is this handled on	    */
-	/*	  other XScale processors?				    */
-
-reset_cpu:
-
-	/* We set OWE:WME (watchdog enable) and wait until timeout happens  */
 
-	ldr	r0, =OWER
-	ldr	r1, [r0]
-	orr	r1, r1, #0x0001			/* bit0: WME		    */
-	str	r1, [r0]
-
-	/* OS timer does only wrap every 1165 seconds, so we have to set    */
-	/* the match register as well.					    */
-
-	ldr	r0, =OSCR
-	ldr	r1, [r0]			/* read OS timer	    */
-	add	r1, r1, #0x800			/* let OSMR3 match after    */
-	add	r1, r1, #0x800			/* 4096*(1/3.6864MHz)=1ms   */
-	ldr	r0, =OSMR3
-	str	r1, [r0]
-
-reset_endless:
-
-	b	reset_endless
-
-#ifndef CONFIG_SPL_BUILD
-.section .mmudata, "a"
-	.align	14
-	.globl	mmu_table
-mmu_table:
-	/* 0x00000000 - 0xa0000000 : 1:1, uncached mapping */
-	.set	__base, 0
-	.rept	0xa00
-	.word	(__base << 20) | 0xc12
-	.set	__base, __base + 1
-	.endr
-
-	/* 0xa0000000 - 0xa0100000 : 1:1, cached mapping */
-	.word	(0xa00 << 20) | 0x1c1e
-
-	.set	__base, 0xa01
-	.rept	0x1000 - 0xa01
-	.word	(__base << 20) | 0xc12
-	.set	__base, __base + 1
-	.endr
+#endif
+	.align 5
 #endif	/* CONFIG_SPL_BUILD */
-- 
1.7.6.3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 3/4] OneNAND: Add simple OneNAND SPL
  2011-10-31 13:23 [U-Boot] [PATCH 0/4] Voipac PXA270 OneNAND SPL Marek Vasut
  2011-10-31 13:23 ` [U-Boot] [PATCH 1/4] PXA: Drop Voipac PXA270 OneNAND IPL Marek Vasut
  2011-10-31 13:23 ` [U-Boot] [PATCH 2/4] PXA: Rework start.S to be closer to other ARMs Marek Vasut
@ 2011-10-31 13:23 ` Marek Vasut
  2011-10-31 23:15   ` Scott Wood
  2011-11-01 22:54   ` [U-Boot] [PATCH 3/4 V2] " Marek Vasut
  2011-10-31 13:23 ` [U-Boot] [PATCH 4/4] PXA: Adapt Voipac PXA270 to " Marek Vasut
  3 siblings, 2 replies; 38+ messages in thread
From: Marek Vasut @ 2011-10-31 13:23 UTC (permalink / raw)
  To: u-boot

This introduces small OneNAND loader, fitting into 1kB of space (smallest
possible OneNAND RAM size). Some devices equipped with such crappy chips will
use this.

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Scott Wood <scottwood@freescale.com>
---
 drivers/mtd/onenand/Makefile      |    4 +
 drivers/mtd/onenand/onenand_spl.c |  130 +++++++++++++++++++++++++++++++++++++
 include/onenand_uboot.h           |   18 +++++
 spl/Makefile                      |    1 +
 4 files changed, 153 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/onenand/onenand_spl.c

diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
index b984bd4..b090d40 100644
--- a/drivers/mtd/onenand/Makefile
+++ b/drivers/mtd/onenand/Makefile
@@ -25,8 +25,12 @@ include $(TOPDIR)/config.mk
 
 LIB	:= $(obj)libonenand.o
 
+ifndef	CONFIG_SPL_BUILD
 COBJS-$(CONFIG_CMD_ONENAND)	:= onenand_uboot.o onenand_base.o onenand_bbt.o
 COBJS-$(CONFIG_SAMSUNG_ONENAND)	+= samsung.o
+else
+COBJS-y				:= onenand_spl.o
+endif
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/mtd/onenand/onenand_spl.c b/drivers/mtd/onenand/onenand_spl.c
new file mode 100644
index 0000000..5429972
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_spl.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on code:
+ *	Copyright (C) 2005-2009 Samsung Electronics
+ *	Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * 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>
+#include <asm/io.h>
+#include <linux/mtd/onenand_regs.h>
+#include <onenand_uboot.h>
+
+inline uint16_t onenand_readw(uint32_t addr)
+{
+	return readw(CONFIG_SYS_ONENAND_BASE + addr);
+}
+
+inline void onenand_writew(uint16_t value, uint32_t addr)
+{
+	writew(value, CONFIG_SYS_ONENAND_BASE + addr);
+}
+
+
+#define	onenand_block_address(block)		(block)
+#define	onenand_sector_address(page)		(page << 2)
+#define	onenand_buffer_address()		((1 << 3) << 8)
+#define	onenand_bufferram_address(block)	(0)
+
+void spl_onenand_get_geometry(struct spl_onenand_data *data)
+{
+	uint32_t tmp;
+	uint32_t dev_id, density;
+
+	/* Default geometry -- 2048b page, 128k erase block. */
+	data->pagesize = 2048;
+	data->erasesize = 0x20000;
+
+	tmp = onenand_readw(ONENAND_REG_TECHNOLOGY);
+	if (tmp)
+		goto dev_4k;
+
+	dev_id = onenand_readw(ONENAND_REG_DEVICE_ID);
+	density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
+	density &= ONENAND_DEVICE_DENSITY_MASK;
+
+	if (density < ONENAND_DEVICE_DENSITY_4Gb)
+		return;
+
+	if (dev_id & ONENAND_DEVICE_IS_DDP)
+		return;
+
+	/* 4k device geometry -- 4096b page, 256k erase block. */
+dev_4k:
+	data->pagesize = 4096;
+	data->erasesize = 0x40000;
+}
+
+int spl_onenand_read_page(uint32_t block, uint32_t page,
+				uint8_t *buf, int pagesize)
+{
+	const uint32_t addr = CONFIG_SYS_ONENAND_BASE + ONENAND_DATARAM;
+	uint32_t offset;
+
+	onenand_writew(onenand_block_address(block),
+			ONENAND_REG_START_ADDRESS1);
+
+	onenand_writew(onenand_bufferram_address(block),
+			ONENAND_REG_START_ADDRESS2);
+
+	onenand_writew(onenand_sector_address(page),
+			ONENAND_REG_START_ADDRESS8);
+
+	onenand_writew(onenand_buffer_address(),
+			ONENAND_REG_START_BUFFER);
+
+	onenand_writew(ONENAND_INT_CLEAR, ONENAND_REG_INTERRUPT);
+
+	onenand_writew(ONENAND_CMD_READ, ONENAND_REG_COMMAND);
+
+	while (!(onenand_readw(ONENAND_REG_INTERRUPT) & ONENAND_INT_READ))
+		continue;
+
+	/* Check for invalid block mark */
+	if (page < 2 && (onenand_readw(ONENAND_SPARERAM) != 0xffff))
+		return 1;
+
+	for (offset = 0; offset < pagesize; offset++)
+		buf[offset] = readb(addr + offset);
+
+	return 0;
+}
+
+int spl_onenand_read_block(uint32_t block, uint8_t *buf, uint32_t *read)
+{
+	struct spl_onenand_data data;
+	uint32_t page;
+	int ret;
+
+	spl_onenand_get_geometry(&data);
+
+	for (page = 0; page < ONENAND_PAGES_PER_BLOCK; page++) {
+		ret = spl_onenand_read_page(block, page, buf, data.pagesize);
+		if (ret)
+			return ret;
+		buf += data.pagesize;
+	}
+
+	*read = ((block * ONENAND_PAGES_PER_BLOCK) + page) * data.pagesize;
+
+	return 0;
+}
diff --git a/include/onenand_uboot.h b/include/onenand_uboot.h
index 92279d5..66828ce 100644
--- a/include/onenand_uboot.h
+++ b/include/onenand_uboot.h
@@ -16,6 +16,8 @@
 
 #include <linux/types.h>
 
+#ifndef	CONFIG_SPL_BUILD
+
 /* Forward declarations */
 struct mtd_info;
 struct mtd_oob_ops;
@@ -52,4 +54,20 @@ extern int flexonenand_set_boundary(struct mtd_info *mtd, int die,
 extern void s3c64xx_onenand_init(struct mtd_info *);
 extern void s3c64xx_set_width_regs(struct onenand_chip *);
 
+#else
+
+#define ONENAND_PAGES_PER_BLOCK		64
+
+struct spl_onenand_data {
+	uint32_t	pagesize;
+	uint32_t	erasesize;
+};
+
+void spl_onenand_get_geometry(struct spl_onenand_data *data);
+int spl_onenand_read_page(uint32_t block, uint32_t page,
+				uint8_t *buf, int pagesize);
+int spl_onenand_read_block(uint32_t block, uint8_t *buf, uint32_t *read);
+
+#endif
+
 #endif /* __UBOOT_ONENAND_H */
diff --git a/spl/Makefile b/spl/Makefile
index ed1f770..d4184ac 100644
--- a/spl/Makefile
+++ b/spl/Makefile
@@ -54,6 +54,7 @@ LIBS-$(CONFIG_SPL_FAT_SUPPORT) += fs/fat/libfat.o
 LIBS-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/libgeneric.o
 LIBS-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/libpower.o
 LIBS-$(CONFIG_SPL_NAND_SUPPORT) += drivers/mtd/nand/libnand.o
+LIBS-$(CONFIG_SPL_ONENAND_SUPPORT) += drivers/mtd/onenand/libonenand.o
 LIBS-$(CONFIG_SPL_DMA_SUPPORT) += drivers/dma/libdma.o
 
 ifeq ($(SOC),omap3)
-- 
1.7.6.3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-10-31 13:23 [U-Boot] [PATCH 0/4] Voipac PXA270 OneNAND SPL Marek Vasut
                   ` (2 preceding siblings ...)
  2011-10-31 13:23 ` [U-Boot] [PATCH 3/4] OneNAND: Add simple OneNAND SPL Marek Vasut
@ 2011-10-31 13:23 ` Marek Vasut
  2011-10-31 23:03   ` Scott Wood
  2011-11-01 22:54   ` [U-Boot] [PATCH 4/4 V2] " Marek Vasut
  3 siblings, 2 replies; 38+ messages in thread
From: Marek Vasut @ 2011-10-31 13:23 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
---
 board/vpac270/Makefile    |    6 ++
 board/vpac270/onenand.c   |  136 +++++++++++++++++++++++++++++++++++++++++++++
 board/vpac270/vpac270.c   |    2 +
 include/configs/vpac270.h |   25 +++++++--
 4 files changed, 164 insertions(+), 5 deletions(-)
 create mode 100644 board/vpac270/onenand.c

diff --git a/board/vpac270/Makefile b/board/vpac270/Makefile
index b5c60fd..f25822f 100644
--- a/board/vpac270/Makefile
+++ b/board/vpac270/Makefile
@@ -23,7 +23,13 @@ include $(TOPDIR)/config.mk
 
 LIB	= $(obj)lib$(BOARD).o
 
+ifndef	CONFIG_SPL_BUILD
 COBJS	:= vpac270.o
+endif
+
+ifdef	CONFIG_SPL_BUILD
+COBJS	:= onenand.o
+endif
 
 SRCS	:= $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
diff --git a/board/vpac270/onenand.c b/board/vpac270/onenand.c
new file mode 100644
index 0000000..50de2ab
--- /dev/null
+++ b/board/vpac270/onenand.c
@@ -0,0 +1,136 @@
+/*
+ * Voipac PXA270 OneNAND SPL
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * 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>
+#include <config.h>
+#include <asm/io.h>
+#include <onenand_uboot.h>
+
+extern void pxa_dram_init(void);
+
+inline void spl_copy_self(void)
+{
+	extern uint32_t _end;
+	struct spl_onenand_data data;
+	uint32_t page;
+	uint32_t total_bytes = (uint32_t)&_end - CONFIG_SPL_TEXT_BASE;
+	uint32_t total_pages;
+	uint8_t *addr = (uint8_t *)CONFIG_SPL_TEXT_BASE;
+	int ret;
+
+	spl_onenand_get_geometry(&data);
+
+	/* The page can be either 2k or 4k, avoid using DIV_ROUND_UP. */
+	total_pages = total_bytes >> 11;
+	if (data.pagesize == 4096)
+		total_pages >>= 1;
+
+	for (page = 0; page <= total_pages; page++) {
+		ret = spl_onenand_read_page(0, page, addr, data.pagesize);
+		if (ret)
+			total_pages++;
+		else
+			addr += data.pagesize;
+	}
+}
+
+inline void spl_copy_uboot(void)
+{
+	uint8_t *addr = (uint8_t *)CONFIG_SYS_TEXT_BASE;
+	struct spl_onenand_data data;
+	uint32_t total_pages;
+	uint32_t block;
+	uint32_t page, rpage;
+	int ret;
+
+	spl_onenand_get_geometry(&data);
+
+	/* The page can be either 2k or 4k, avoid using DIV_ROUND_UP. */
+	total_pages = CONFIG_SPL_ONENAND_LOAD_SIZE >> 11;
+	page = CONFIG_SPL_ONENAND_LOAD_ADDR >> 11;
+	if (data.pagesize == 4096) {
+		total_pages >>= 1;
+		page >>= 1;
+	}
+
+	for (; page <= total_pages; page++) {
+		block = page >> 6;
+		rpage = page & 0xff;
+		ret = spl_onenand_read_page(block, rpage, addr, data.pagesize);
+		if (ret)
+			total_pages++;
+		else
+			addr += data.pagesize;
+	}
+}
+
+inline void board_init_f(unsigned long unused)
+{
+	uint32_t tmp;
+
+	asm volatile("mov %0, pc" : "=r"(tmp));
+	tmp >>= 24;
+
+	/* The code runs from OneNAND RAM, copy SPL to SRAM and execute it. */
+	if (tmp == 0) {
+		spl_copy_self();
+		asm volatile("mov pc, %0" : : "r"(CONFIG_SPL_TEXT_BASE));
+	}
+
+	/* Hereby, the code runs from (S)RAM, copy U-Boot and execute it. */
+	arch_cpu_init();
+	pxa_dram_init();
+	spl_copy_uboot();
+	asm volatile("mov pc, %0" : : "r"(CONFIG_SYS_TEXT_BASE));
+
+	for (;;)
+		;
+}
+
+inline void board_init_r(gd_t *id, ulong dest_addr)
+{
+	for (;;)
+		;
+}
+
+inline int printf(const char *fmt, ...)
+{
+	return 0;
+}
+
+inline void __coloured_LED_init(void) {}
+inline void __red_LED_on(void) {}
+void coloured_LED_init(void)
+	__attribute__((weak, alias("__coloured_LED_init")));
+void red_LED_on(void)
+	__attribute__((weak, alias("__red_LED_on")));
+void hang(void) __attribute__ ((noreturn));
+void hang(void)
+{
+	for (;;)
+		;
+}
+
+inline void icache_disable(void) {}
+inline void dcache_disable(void) {}
diff --git a/board/vpac270/vpac270.c b/board/vpac270/vpac270.c
index 43bbdff..f146009 100644
--- a/board/vpac270/vpac270.c
+++ b/board/vpac270/vpac270.c
@@ -56,7 +56,9 @@ struct serial_device *default_serial_console(void)
 extern void pxa_dram_init(void);
 int dram_init(void)
 {
+#ifndef	CONFIG_ONENAND
 	pxa_dram_init();
+#endif
 	gd->ram_size = PHYS_SDRAM_1_SIZE;
 	return 0;
 }
diff --git a/include/configs/vpac270.h b/include/configs/vpac270.h
index 9db4d99..d43ff47 100644
--- a/include/configs/vpac270.h
+++ b/include/configs/vpac270.h
@@ -27,7 +27,17 @@
  */
 #define	CONFIG_PXA27X		1	/* Marvell PXA270 CPU */
 #define	CONFIG_VPAC270		1	/* Voipac PXA270 board */
-#define	CONFIG_SYS_TEXT_BASE	0x0
+#define	CONFIG_SYS_TEXT_BASE	0xa0000000
+
+#ifdef	CONFIG_ONENAND
+#define	CONFIG_SPL
+#define	CONFIG_SPL_ONENAND_SUPPORT
+#define	CONFIG_SPL_ONENAND_LOAD_ADDR	0x2000
+#define	CONFIG_SPL_ONENAND_LOAD_SIZE	\
+	(512 * 1024 - CONFIG_SPL_ONENAND_LOAD_ADDR)
+#define	CONFIG_SPL_TEXT_BASE	0x5c000000
+#define	CONFIG_SPL_LDSCRIPT	"board/vpac270/u-boot-spl.lds"
+#endif
 
 /*
  * Environment settings
@@ -46,12 +56,19 @@
 		"bootm 0xa4000000; "					\
 	"fi; "								\
 	"bootm 0x60000;"
+
+#define	CONFIG_EXTRA_ENV_SETTINGS					\
+	"update_onenand="						\
+		"onenand erase 0x0 0x80000 ; "				\
+		"onenand write 0xa0000000 0x0 0x80000"
+
 #define	CONFIG_BOOTARGS			"console=tty0 console=ttyS0,115200"
 #define	CONFIG_TIMESTAMP
 #define	CONFIG_BOOTDELAY		2	/* Autoboot delay */
 #define	CONFIG_CMDLINE_TAG
 #define	CONFIG_SETUP_MEMORY_TAGS
 #define	CONFIG_LZMA			/* LZMA compression support */
+#define	CONFIG_OF_LIBFDT
 
 /*
  * Serial Console Configuration
@@ -179,16 +196,14 @@
 #define	CONFIG_SYS_MEMTEST_END		0xa0800000	/* 4 ... 8 MB in DRAM */
 
 #define	CONFIG_SYS_LOAD_ADDR		PHYS_SDRAM_1
-#define	CONFIG_SYS_IPL_LOAD_ADDR	(0x5c000000)
 #define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
-#define	CONFIG_SYS_INIT_SP_ADDR		\
-	(PHYS_SDRAM_1 + GENERATED_GBL_DATA_SIZE + 2048)
+#define	CONFIG_SYS_INIT_SP_ADDR		0x5c010000
 
 /*
  * NOR FLASH
  */
 #define	CONFIG_SYS_MONITOR_BASE		0x0
-#define	CONFIG_SYS_MONITOR_LEN		0x40000
+#define	CONFIG_SYS_MONITOR_LEN		0x80000
 #define	CONFIG_ENV_ADDR			\
 			(CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN)
 #define	CONFIG_ENV_SIZE			0x4000
-- 
1.7.6.3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-10-31 13:23 ` [U-Boot] [PATCH 4/4] PXA: Adapt Voipac PXA270 to " Marek Vasut
@ 2011-10-31 23:03   ` Scott Wood
  2011-11-01 22:12     ` Marek Vasut
  2011-11-01 22:54   ` [U-Boot] [PATCH 4/4 V2] " Marek Vasut
  1 sibling, 1 reply; 38+ messages in thread
From: Scott Wood @ 2011-10-31 23:03 UTC (permalink / raw)
  To: u-boot

On 10/31/2011 08:23 AM, Marek Vasut wrote:
> Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
> Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
> ---
>  board/vpac270/Makefile    |    6 ++
>  board/vpac270/onenand.c   |  136 +++++++++++++++++++++++++++++++++++++++++++++
>  board/vpac270/vpac270.c   |    2 +
>  include/configs/vpac270.h |   25 +++++++--
>  4 files changed, 164 insertions(+), 5 deletions(-)
>  create mode 100644 board/vpac270/onenand.c
> 
> diff --git a/board/vpac270/Makefile b/board/vpac270/Makefile
> index b5c60fd..f25822f 100644
> --- a/board/vpac270/Makefile
> +++ b/board/vpac270/Makefile
> @@ -23,7 +23,13 @@ include $(TOPDIR)/config.mk
>  
>  LIB	= $(obj)lib$(BOARD).o
>  
> +ifndef	CONFIG_SPL_BUILD
>  COBJS	:= vpac270.o
> +endif
> +
> +ifdef	CONFIG_SPL_BUILD
> +COBJS	:= onenand.o
> +endif

else?

>  SRCS	:= $(COBJS:.o=.c)
>  OBJS	:= $(addprefix $(obj),$(COBJS))
> diff --git a/board/vpac270/onenand.c b/board/vpac270/onenand.c
> new file mode 100644
> index 0000000..50de2ab
> --- /dev/null
> +++ b/board/vpac270/onenand.c
> @@ -0,0 +1,136 @@
> +/*
> + * Voipac PXA270 OneNAND SPL
> + *
> + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
> + *
> + * 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>
> +#include <config.h>
> +#include <asm/io.h>
> +#include <onenand_uboot.h>
> +
> +extern void pxa_dram_init(void);
> +
> +inline void spl_copy_self(void)
> +{
> +	extern uint32_t _end;
> +	struct spl_onenand_data data;
> +	uint32_t page;
> +	uint32_t total_bytes = (uint32_t)&_end - CONFIG_SPL_TEXT_BASE;
> +	uint32_t total_pages;
> +	uint8_t *addr = (uint8_t *)CONFIG_SPL_TEXT_BASE;
> +	int ret;
> +
> +	spl_onenand_get_geometry(&data);
> +
> +	/* The page can be either 2k or 4k, avoid using DIV_ROUND_UP. */
> +	total_pages = total_bytes >> 11;
> +	if (data.pagesize == 4096)
> +		total_pages >>= 1;

total_bytes / 2048 and total_pages / 2 are more readable and should
generate exactly the same code.

> +	for (page = 0; page <= total_pages; page++) {
> +		ret = spl_onenand_read_page(0, page, addr, data.pagesize);
> +		if (ret)
> +			total_pages++;
> +		else
> +			addr += data.pagesize;
> +	}
> +}

You want to skip to the next block if spl_onenand_read_page() fails
(which can occur after you've already read some of the block).

How much of this is board-specific?

> +inline void spl_copy_uboot(void)
> +{
> +	uint8_t *addr = (uint8_t *)CONFIG_SYS_TEXT_BASE;
> +	struct spl_onenand_data data;
> +	uint32_t total_pages;
> +	uint32_t block;
> +	uint32_t page, rpage;
> +	int ret;
> +
> +	spl_onenand_get_geometry(&data);
> +
> +	/* The page can be either 2k or 4k, avoid using DIV_ROUND_UP. */
> +	total_pages = CONFIG_SPL_ONENAND_LOAD_SIZE >> 11;
> +	page = CONFIG_SPL_ONENAND_LOAD_ADDR >> 11;
> +	if (data.pagesize == 4096) {
> +		total_pages >>= 1;
> +		page >>= 1;
> +	}
> +
> +	for (; page <= total_pages; page++) {
> +		block = page >> 6;
> +		rpage = page & 0xff;
> +		ret = spl_onenand_read_page(block, rpage, addr, data.pagesize);
> +		if (ret)
> +			total_pages++;
> +		else
> +			addr += data.pagesize;
> +	}
> +}

What is so different about this compared to spl_copy_self, that warrants
such duplication?  Can't you just pass in offset, length, and
destination as parameters?  Or just have the OneNAND SPL driver export
nand_spl_load_image(), as any other NAND SPL driver would?

> +inline void board_init_f(unsigned long unused)
> +{
> +	uint32_t tmp;
> +
> +	asm volatile("mov %0, pc" : "=r"(tmp));
> +	tmp >>= 24;
> +
> +	/* The code runs from OneNAND RAM, copy SPL to SRAM and execute it. */
> +	if (tmp == 0) {
> +		spl_copy_self();
> +		asm volatile("mov pc, %0" : : "r"(CONFIG_SPL_TEXT_BASE));
> +	}

Is it not possible to use a simple memcpy for spl_copy_self()?  If the
CPU can run the code, you'd think it could read it.

> +inline void board_init_r(gd_t *id, ulong dest_addr)
> +{
> +	for (;;)
> +		;
> +}

This doesn't seem like a useful board_init_r().  If you don't need it,
maybe make sure it's not called, and save yourself some bytes in the
SPL.  Likewise for the other stub functions, where practical.

> +inline int printf(const char *fmt, ...)
> +{
> +	return 0;
> +}
> +
> +inline void __coloured_LED_init(void) {}
> +inline void __red_LED_on(void) {}
> +void coloured_LED_init(void)
> +	__attribute__((weak, alias("__coloured_LED_init")));
> +void red_LED_on(void)
> +	__attribute__((weak, alias("__red_LED_on")));
> +void hang(void) __attribute__ ((noreturn));
> +void hang(void)
> +{
> +	for (;;)
> +		;
> +}
> +
> +inline void icache_disable(void) {}
> +inline void dcache_disable(void) {}

Why are you specifying inline on just about everything, even functions
that are not used in this file?

Why are you not specifying static on things that are not needed outside
this file?

> diff --git a/board/vpac270/vpac270.c b/board/vpac270/vpac270.c
> index 43bbdff..f146009 100644
> --- a/board/vpac270/vpac270.c
> +++ b/board/vpac270/vpac270.c
> @@ -56,7 +56,9 @@ struct serial_device *default_serial_console(void)
>  extern void pxa_dram_init(void);
>  int dram_init(void)
>  {
> +#ifndef	CONFIG_ONENAND
>  	pxa_dram_init();
> +#endif
>  	gd->ram_size = PHYS_SDRAM_1_SIZE;
>  	return 0;
>  }

Should this really be about whether OneNAND support is present, or
should it be based on whether you're using the OneNAND SPL?

-Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 3/4] OneNAND: Add simple OneNAND SPL
  2011-10-31 13:23 ` [U-Boot] [PATCH 3/4] OneNAND: Add simple OneNAND SPL Marek Vasut
@ 2011-10-31 23:15   ` Scott Wood
  2011-11-01 22:54   ` [U-Boot] [PATCH 3/4 V2] " Marek Vasut
  1 sibling, 0 replies; 38+ messages in thread
From: Scott Wood @ 2011-10-31 23:15 UTC (permalink / raw)
  To: u-boot

On 10/31/2011 08:23 AM, Marek Vasut wrote:
> +inline uint16_t onenand_readw(uint32_t addr)
> +{
> +	return readw(CONFIG_SYS_ONENAND_BASE + addr);
> +}
> +
> +inline void onenand_writew(uint16_t value, uint32_t addr)
> +{
> +	writew(value, CONFIG_SYS_ONENAND_BASE + addr);
> +}

static

> +#define	onenand_block_address(block)		(block)
> +#define	onenand_sector_address(page)		(page << 2)
> +#define	onenand_buffer_address()		((1 << 3) << 8)
> +#define	onenand_bufferram_address(block)	(0)

Space rather than tab after #define

> +void spl_onenand_get_geometry(struct spl_onenand_data *data)
> +{
> +	uint32_t tmp;
> +	uint32_t dev_id, density;
> +
> +	/* Default geometry -- 2048b page, 128k erase block. */
> +	data->pagesize = 2048;
> +	data->erasesize = 0x20000;
> +
> +	tmp = onenand_readw(ONENAND_REG_TECHNOLOGY);
> +	if (tmp)
> +		goto dev_4k;
> +
> +	dev_id = onenand_readw(ONENAND_REG_DEVICE_ID);
> +	density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
> +	density &= ONENAND_DEVICE_DENSITY_MASK;
> +
> +	if (density < ONENAND_DEVICE_DENSITY_4Gb)
> +		return;
> +
> +	if (dev_id & ONENAND_DEVICE_IS_DDP)
> +		return;
> +
> +	/* 4k device geometry -- 4096b page, 256k erase block. */
> +dev_4k:
> +	data->pagesize = 4096;
> +	data->erasesize = 0x40000;
> +}

This seems like a gratuitous use of goto...

> +int spl_onenand_read_block(uint32_t block, uint8_t *buf, uint32_t *read)
> +{
> +	struct spl_onenand_data data;
> +	uint32_t page;
> +	int ret;
> +
> +	spl_onenand_get_geometry(&data);
> +
> +	for (page = 0; page < ONENAND_PAGES_PER_BLOCK; page++) {
> +		ret = spl_onenand_read_page(block, page, buf, data.pagesize);
> +		if (ret)
> +			return ret;
> +		buf += data.pagesize;
> +	}

Shouldn't this do bad block skipping rather than error on the first bad
block it sees?  The current onenand IPL does this.

> +	*read = ((block * ONENAND_PAGES_PER_BLOCK) + page) * data.pagesize;

We only read one block here, but we return the byte address of the next
block?  A little odd, and if it's really what's intended, needs to be
documented.

> diff --git a/include/onenand_uboot.h b/include/onenand_uboot.h
> index 92279d5..66828ce 100644
> --- a/include/onenand_uboot.h
> +++ b/include/onenand_uboot.h
> @@ -16,6 +16,8 @@
>  
>  #include <linux/types.h>
>  
> +#ifndef	CONFIG_SPL_BUILD
> +
>  /* Forward declarations */
>  struct mtd_info;
>  struct mtd_oob_ops;
> @@ -52,4 +54,20 @@ extern int flexonenand_set_boundary(struct mtd_info *mtd, int die,
>  extern void s3c64xx_onenand_init(struct mtd_info *);
>  extern void s3c64xx_set_width_regs(struct onenand_chip *);
>  
> +#else
> +
> +#define ONENAND_PAGES_PER_BLOCK		64
> +
> +struct spl_onenand_data {
> +	uint32_t	pagesize;
> +	uint32_t	erasesize;
> +};
> +
> +void spl_onenand_get_geometry(struct spl_onenand_data *data);
> +int spl_onenand_read_page(uint32_t block, uint32_t page,
> +				uint8_t *buf, int pagesize);
> +int spl_onenand_read_block(uint32_t block, uint8_t *buf, uint32_t *read);
> +
> +#endif

Do these really need to be #ifdeffed?

-Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-10-31 23:03   ` Scott Wood
@ 2011-11-01 22:12     ` Marek Vasut
  2011-11-01 22:34       ` Scott Wood
  0 siblings, 1 reply; 38+ messages in thread
From: Marek Vasut @ 2011-11-01 22:12 UTC (permalink / raw)
  To: u-boot

> On 10/31/2011 08:23 AM, Marek Vasut wrote:
> > Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
> > Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
> > ---
[...]

> 
> > +	for (page = 0; page <= total_pages; page++) {
> > +		ret = spl_onenand_read_page(0, page, addr, data.pagesize);
> > +		if (ret)
> > +			total_pages++;
> > +		else
> > +			addr += data.pagesize;
> > +	}
> > +}
> 
> You want to skip to the next block if spl_onenand_read_page() fails
> (which can occur after you've already read some of the block).

I want to skip to next page, not next block.

> 
> How much of this is board-specific?
> 
> > +inline void spl_copy_uboot(void)
> > +{
> > +	uint8_t *addr = (uint8_t *)CONFIG_SYS_TEXT_BASE;
> > +	struct spl_onenand_data data;
> > +	uint32_t total_pages;
> > +	uint32_t block;
> > +	uint32_t page, rpage;
> > +	int ret;
> > +
> > +	spl_onenand_get_geometry(&data);
> > +
> > +	/* The page can be either 2k or 4k, avoid using DIV_ROUND_UP. */
> > +	total_pages = CONFIG_SPL_ONENAND_LOAD_SIZE >> 11;
> > +	page = CONFIG_SPL_ONENAND_LOAD_ADDR >> 11;
> > +	if (data.pagesize == 4096) {
> > +		total_pages >>= 1;
> > +		page >>= 1;
> > +	}
> > +
> > +	for (; page <= total_pages; page++) {
> > +		block = page >> 6;
> > +		rpage = page & 0xff;
> > +		ret = spl_onenand_read_page(block, rpage, addr, data.pagesize);
> > +		if (ret)
> > +			total_pages++;
> > +		else
> > +			addr += data.pagesize;
> > +	}
> > +}
> 
> What is so different about this compared to spl_copy_self, that warrants
> such duplication?  Can't you just pass in offset, length, and
> destination as parameters?  Or just have the OneNAND SPL driver export
> nand_spl_load_image(), as any other NAND SPL driver would?

Good idea.

> 
> > +inline void board_init_f(unsigned long unused)
> > +{
> > +	uint32_t tmp;
> > +
> > +	asm volatile("mov %0, pc" : "=r"(tmp));
> > +	tmp >>= 24;
> > +
> > +	/* The code runs from OneNAND RAM, copy SPL to SRAM and execute it. */
> > +	if (tmp == 0) {
> > +		spl_copy_self();
> > +		asm volatile("mov pc, %0" : : "r"(CONFIG_SPL_TEXT_BASE));
> > +	}
> 
> Is it not possible to use a simple memcpy for spl_copy_self()?  If the
> CPU can run the code, you'd think it could read it.

Not exactly. The OneNAND only exposes first 1kb of the contents (aka 1 half of 
the page 0 in my case). That's why I link all of the relevant code there and the 
rest of the SPL is aligned beyond that. Then I copy the whole SPL to SRAM and 
execute it again. Then I init DRAM, copy U-Boot there and run it. Simple, isn't 
it.

> 
> > +inline void board_init_r(gd_t *id, ulong dest_addr)
> > +{
> > +	for (;;)
> > +		;
> > +}
> 
> This doesn't seem like a useful board_init_r().  If you don't need it,
> maybe make sure it's not called, and save yourself some bytes in the
> SPL.  Likewise for the other stub functions, where practical.
> 
> > +inline int printf(const char *fmt, ...)
> > +{
> > +	return 0;
> > +}
> > +
> > +inline void __coloured_LED_init(void) {}
> > +inline void __red_LED_on(void) {}
> > +void coloured_LED_init(void)
> > +	__attribute__((weak, alias("__coloured_LED_init")));
> > +void red_LED_on(void)
> > +	__attribute__((weak, alias("__red_LED_on")));
> > +void hang(void) __attribute__ ((noreturn));
> > +void hang(void)
> > +{
> > +	for (;;)
> > +		;
> > +}
> > +
> > +inline void icache_disable(void) {}
> > +inline void dcache_disable(void) {}
> 
> Why are you specifying inline on just about everything, even functions
> that are not used in this file?

They are, by dram_init();

> 
> Why are you not specifying static on things that are not needed outside
> this file?

They are actually needed outside.
> 
> > diff --git a/board/vpac270/vpac270.c b/board/vpac270/vpac270.c
> > index 43bbdff..f146009 100644
> > --- a/board/vpac270/vpac270.c
> > +++ b/board/vpac270/vpac270.c
> > @@ -56,7 +56,9 @@ struct serial_device *default_serial_console(void)
> > 
> >  extern void pxa_dram_init(void);
> >  int dram_init(void)
> >  {
> > 
> > +#ifndef	CONFIG_ONENAND
> > 
> >  	pxa_dram_init();
> > 
> > +#endif
> > 
> >  	gd->ram_size = PHYS_SDRAM_1_SIZE;
> >  	return 0;
> >  
> >  }
> 
> Should this really be about whether OneNAND support is present, or
> should it be based on whether you're using the OneNAND SPL?

Basically, on this board this is the same thing.
> 
> -Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-11-01 22:12     ` Marek Vasut
@ 2011-11-01 22:34       ` Scott Wood
  2011-11-01 22:44         ` Marek Vasut
  0 siblings, 1 reply; 38+ messages in thread
From: Scott Wood @ 2011-11-01 22:34 UTC (permalink / raw)
  To: u-boot

On 11/01/2011 05:12 PM, Marek Vasut wrote:
>> On 10/31/2011 08:23 AM, Marek Vasut wrote:
>>> Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
>>> Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
>>> ---
> [...]
> 
>>
>>> +	for (page = 0; page <= total_pages; page++) {
>>> +		ret = spl_onenand_read_page(0, page, addr, data.pagesize);
>>> +		if (ret)
>>> +			total_pages++;
>>> +		else
>>> +			addr += data.pagesize;
>>> +	}
>>> +}
>>
>> You want to skip to the next block if spl_onenand_read_page() fails
>> (which can occur after you've already read some of the block).
> 
> I want to skip to next page, not next block.

That's not how we normally do things, and is not what the current
OneNAND IPL does.

Bad block markers apply to the entire block -- unless this is a
difference I'm not aware of between NAND and OneNAND.

>> Is it not possible to use a simple memcpy for spl_copy_self()?  If the
>> CPU can run the code, you'd think it could read it.
> 
> Not exactly. The OneNAND only exposes first 1kb of the contents (aka 1 half of 
> the page 0 in my case). That's why I link all of the relevant code there and the 
> rest of the SPL is aligned beyond that. Then I copy the whole SPL to SRAM and 
> execute it again. Then I init DRAM, copy U-Boot there and run it. Simple, isn't 
> it.

Where do you ensure that the stuff used so far is within the 1K?  What
parts are not within the 1K?

I don't see a linker script.

>>> +inline void icache_disable(void) {}
>>> +inline void dcache_disable(void) {}
>>
>> Why are you specifying inline on just about everything, even functions
>> that are not used in this file?
> 
> They are, by dram_init();

There's no point marking something inline if it's not used later on in
the same file -- functions aren't inlined across file boundaries.
You've got inline functions at the very end of the file.

For that matter, there's not much point marking anything inline that
isn't a static inline in a header file (where the compiler must not
generate a non-inline version) -- the compiler has heuristics for
inlining things, and excessive inlining tends to make things bigger
rather than smaller.

>> Why are you not specifying static on things that are not needed outside
>> this file?
> 
> They are actually needed outside.

All of them, including spl_copy_uboot and spl_copy_self?

>>> diff --git a/board/vpac270/vpac270.c b/board/vpac270/vpac270.c
>>> index 43bbdff..f146009 100644
>>> --- a/board/vpac270/vpac270.c
>>> +++ b/board/vpac270/vpac270.c
>>> @@ -56,7 +56,9 @@ struct serial_device *default_serial_console(void)
>>>
>>>  extern void pxa_dram_init(void);
>>>  int dram_init(void)
>>>  {
>>>
>>> +#ifndef	CONFIG_ONENAND
>>>
>>>  	pxa_dram_init();
>>>
>>> +#endif
>>>
>>>  	gd->ram_size = PHYS_SDRAM_1_SIZE;
>>>  	return 0;
>>>  
>>>  }
>>
>> Should this really be about whether OneNAND support is present, or
>> should it be based on whether you're using the OneNAND SPL?
> 
> Basically, on this board this is the same thing.

If you can turn off onenand at all, that suggests there's another boot
source.  Is it not possible to access onenand when using that other boot
source?

In any case, best to use the symbol that most closely matches the reason
you're skipping it, which is something SPL-related.

-Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-11-01 22:34       ` Scott Wood
@ 2011-11-01 22:44         ` Marek Vasut
  2011-11-02 22:18           ` Scott Wood
  0 siblings, 1 reply; 38+ messages in thread
From: Marek Vasut @ 2011-11-01 22:44 UTC (permalink / raw)
  To: u-boot

> On 11/01/2011 05:12 PM, Marek Vasut wrote:
> >> On 10/31/2011 08:23 AM, Marek Vasut wrote:
> >>> Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
> >>> Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
> >>> ---
> > 
> > [...]
> > 
> >>> +	for (page = 0; page <= total_pages; page++) {
> >>> +		ret = spl_onenand_read_page(0, page, addr, data.pagesize);
> >>> +		if (ret)
> >>> +			total_pages++;
> >>> +		else
> >>> +			addr += data.pagesize;
> >>> +	}
> >>> +}
> >> 
> >> You want to skip to the next block if spl_onenand_read_page() fails
> >> (which can occur after you've already read some of the block).
> > 
> > I want to skip to next page, not next block.
> 
> That's not how we normally do things, and is not what the current
> OneNAND IPL does.
> 
> Bad block markers apply to the entire block -- unless this is a
> difference I'm not aware of between NAND and OneNAND.

Well then it will fail reading the whole block and continue onwards ... it's a 
bit slower like this.

> 
> >> Is it not possible to use a simple memcpy for spl_copy_self()?  If the
> >> CPU can run the code, you'd think it could read it.
> > 
> > Not exactly. The OneNAND only exposes first 1kb of the contents (aka 1
> > half of the page 0 in my case). That's why I link all of the relevant
> > code there and the rest of the SPL is aligned beyond that. Then I copy
> > the whole SPL to SRAM and execute it again. Then I init DRAM, copy
> > U-Boot there and run it. Simple, isn't it.
> 
> Where do you ensure that the stuff used so far is within the 1K?  What
> parts are not within the 1K?
> 
> I don't see a linker script.

Is in V2, missing.

> 
> >>> +inline void icache_disable(void) {}
> >>> +inline void dcache_disable(void) {}
> >> 
> >> Why are you specifying inline on just about everything, even functions
> >> that are not used in this file?
> > 
> > They are, by dram_init();
> 
> There's no point marking something inline if it's not used later on in
> the same file -- functions aren't inlined across file boundaries.
> You've got inline functions at the very end of the file.
> 
> For that matter, there's not much point marking anything inline that
> isn't a static inline in a header file (where the compiler must not
> generate a non-inline version) -- the compiler has heuristics for
> inlining things, and excessive inlining tends to make things bigger
> rather than smaller.
> 
> >> Why are you not specifying static on things that are not needed outside
> >> this file?
> > 
> > They are actually needed outside.
> 
> All of them, including spl_copy_uboot and spl_copy_self?
> 
> >>> diff --git a/board/vpac270/vpac270.c b/board/vpac270/vpac270.c
> >>> index 43bbdff..f146009 100644
> >>> --- a/board/vpac270/vpac270.c
> >>> +++ b/board/vpac270/vpac270.c
> >>> @@ -56,7 +56,9 @@ struct serial_device *default_serial_console(void)
> >>> 
> >>>  extern void pxa_dram_init(void);
> >>>  int dram_init(void)
> >>>  {
> >>> 
> >>> +#ifndef	CONFIG_ONENAND
> >>> 
> >>>  	pxa_dram_init();
> >>> 
> >>> +#endif
> >>> 
> >>>  	gd->ram_size = PHYS_SDRAM_1_SIZE;
> >>>  	return 0;
> >>>  
> >>>  }
> >> 
> >> Should this really be about whether OneNAND support is present, or
> >> should it be based on whether you're using the OneNAND SPL?
> > 
> > Basically, on this board this is the same thing.
> 
> If you can turn off onenand at all, that suggests there's another boot
> source.  Is it not possible to access onenand when using that other boot
> source?

No, they are mutually exclusive.

> 
> In any case, best to use the symbol that most closely matches the reason
> you're skipping it, which is something SPL-related.
> 
> -Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 2/4 V2] PXA: Rework start.S to be closer to other ARMs
  2011-10-31 13:23 ` [U-Boot] [PATCH 2/4] PXA: Rework start.S to be closer to other ARMs Marek Vasut
@ 2011-11-01 22:53   ` Marek Vasut
  2011-11-02  9:01   ` [U-Boot] [PATCH 2/4] " Stefan Herbrechtsmeier
  1 sibling, 0 replies; 38+ messages in thread
From: Marek Vasut @ 2011-11-01 22:53 UTC (permalink / raw)
  To: u-boot

The start.S on PXA was very obscure. This reworks it back to be close to arm1136
start.S and others.

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
---
 arch/arm/cpu/pxa/cpu.c   |   16 ++
 arch/arm/cpu/pxa/start.S |  384 ++++++++++++++++-----------------------------
 2 files changed, 153 insertions(+), 247 deletions(-)

V2: Don't compile in relocation support if building SPL

diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c
index df351c7..c48b2ef 100644
--- a/arch/arm/cpu/pxa/cpu.c
+++ b/arch/arm/cpu/pxa/cpu.c
@@ -328,3 +328,19 @@ void i2c_clk_enable(void)
 	writel(readl(CKEN) | CKEN14_I2C, CKEN);
 #endif
 }
+
+void reset_cpu(ulong ignored) __attribute__((noreturn));
+
+void reset_cpu(ulong ignored)
+{
+	uint32_t tmp;
+
+	setbits_le32(OWER, OWER_WME);
+
+	tmp = readl(OSCR);
+	tmp += 0x1000;
+	writel(tmp, OSMR3);
+
+	for (;;)
+		;
+}
diff --git a/arch/arm/cpu/pxa/start.S b/arch/arm/cpu/pxa/start.S
index 6191a73..88a4cc2 100644
--- a/arch/arm/cpu/pxa/start.S
+++ b/arch/arm/cpu/pxa/start.S
@@ -1,14 +1,20 @@
 /*
- *  armboot - Startup Code for XScale
+ *  armboot - Startup Code for XScale CPU-core
  *
  *  Copyright (C) 1998	Dan Malek <dmalek@jlc.net>
  *  Copyright (C) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
  *  Copyright (C) 2000	Wolfgang Denk <wd@denx.de>
  *  Copyright (C) 2001	Alex Zuepke <azu@sysgo.de>
+ *  Copyright (C) 2001	Marius Groger <mag@sysgo.de>
+ *  Copyright (C) 2002	Alex Zupke <azu@sysgo.de>
+ *  Copyright (C) 2002	Gary Jennejohn <garyj@denx.de>
  *  Copyright (C) 2002	Kyle Harris <kharris@nexus-tech.net>
- *  Copyright (C) 2003	Robert Schwebel <r.schwebel@pengutronix.de>
  *  Copyright (C) 2003	Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de>
- *  Copyright (c) 2010	Marek Vasut <marek.vasut@gmail.com>
+ *  Copyright (C) 2003	Kshitij <kshitij@ti.com>
+ *  Copyright (C) 2003	Richard Woodruff <r-woodruff2@ti.com>
+ *  Copyright (C) 2003	Robert Schwebel <r.schwebel@pengutronix.de>
+ *  Copyright (C) 2004	Texas Instruments <r-woodruff2@ti.com>
+ *  Copyright (C) 2010	Marek Vasut <marek.vasut@gmail.com>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -32,15 +38,6 @@
 #include <asm-offsets.h>
 #include <config.h>
 #include <version.h>
-#include <asm/arch/pxa-regs.h>
-
-/* takes care the CP15 update has taken place */
-.macro CPWAIT reg
-mrc  p15,0,\reg,c2,c0,0
-mov  \reg,\reg
-sub  pc,pc,#4
-.endm
-
 .globl _start
 _start: b	reset
 #ifdef CONFIG_SPL_BUILD
@@ -77,26 +74,38 @@ _data_abort:		.word data_abort
 _not_used:		.word not_used
 _irq:			.word irq
 _fiq:			.word fiq
+_pad:			.word 0x12345678 /* now 16*4=64 */
 #endif	/* CONFIG_SPL_BUILD */
+.global _end_vect
+_end_vect:
 
 	.balignl 16,0xdeadbeef
-
-
 /*
+ *************************************************************************
+ *
  * Startup Code (reset vector)
  *
- * do important init only if we don't start from RAM!
- * - relocate armboot to RAM
- * - setup stack
- * - jump to second stage
+ * do important init only if we don't start from memory!
+ * setup Memory and board specific bits prior to relocation.
+ * relocate armboot to ram
+ * setup stack
+ *
+ *************************************************************************
  */
 
 .globl _TEXT_BASE
 _TEXT_BASE:
+#ifdef	CONFIG_SPL_BUILD
+	.word	CONFIG_SPL_TEXT_BASE
+#else
 	.word	CONFIG_SYS_TEXT_BASE
+#endif
 
 /*
  * These are defined in the board-specific linker script.
+ * Subtracting _start from them lets the linker put their
+ * relative position in the executable instead of leaving
+ * them null.
  */
 .globl _bss_start_ofs
 _bss_start_ofs:
@@ -120,9 +129,8 @@ IRQ_STACK_START:
 .globl FIQ_STACK_START
 FIQ_STACK_START:
 	.word 0x0badc0de
-#endif /* CONFIG_USE_IRQ */
+#endif
 
-#ifndef CONFIG_SPL_BUILD
 /* IRQ stack memory (calculated at run-time) + 8 bytes */
 .globl IRQ_STACK_START_IN
 IRQ_STACK_START_IN:
@@ -141,95 +149,19 @@ reset:
 	orr	r0,r0,#0xd3
 	msr	cpsr,r0
 
-	/*
-	 * Enable MMU to use DCache as DRAM
-	 */
-	/* Domain access -- enable for all CPs */
-	ldr	r0, =0x0000ffff
-	mcr	p15, 0, r0, c3, c0, 0
-
-	/* Point TTBR to MMU table */
-	ldr	r0, =mmu_table
-	adr	r2, _start
-	orr	r0, r2
-	mcr	p15, 0, r0, c2, c0, 0
-
-/* !!! Hereby, check if the code is running from SRAM !!! */
-/* If the code is running from SRAM, alias SRAM to 0x0 to simulate NOR. The code
- * is linked to 0x0 too, so this makes things easier. */
-	cmp	r2, #0x5c000000
-
-	ldreq	r1, [r0]
-	orreq	r1, r2
-	streq	r1, [r0]
-
-	/* Kick in MMU, ICache, DCache, BTB */
-	mrc	p15, 0, r0, c1, c0, 0
-	bic	r0, #0x1b00
-	bic	r0, #0x0087
-	orr	r0, #0x1800
-	orr	r0, #0x0005
-	mcr	p15, 0, r0, c1, c0, 0
-	CPWAIT	r0
-
-	/* Unlock Icache, Dcache */
-	mcr	p15, 0, r0, c9, c1, 1
-	mcr	p15, 0, r0, c9, c2, 1
-
-	/* Flush Icache, Dcache, BTB */
-	mcr	p15, 0, r0, c7, c7, 0
-
-	/* Unlock I-TLB, D-TLB */
-	mcr	p15, 0, r0, c10, c4, 1
-	mcr	p15, 0, r0, c10, c8, 1
-
-	/* Flush TLB */
-	mcr	p15, 0, r0, c8, c7, 0
-	/* Allocate 4096 bytes of Dcache as RAM */
-
-	/* Drain pending loads and stores */
-	mcr	p15, 0, r0, c7, c10, 4
-
-	mov	r4, #0x00
-	mov	r5, #0x00
-	mov	r2, #0x01
-	mcr	p15, 0, r0, c9, c2, 0
-	CPWAIT	r0
-
-	/* 128 lines reserved (128 x 32bytes = 4096 bytes total) */
-	mov	r0, #128
-	mov	r1, #0xa0000000
-alloc:
-	mcr	p15, 0, r1, c7, c2, 5
-	/* Drain pending loads and stores */
-	mcr	p15, 0, r0, c7, c10, 4
-	strd	r4, [r1], #8
-	strd	r4, [r1], #8
-	strd	r4, [r1], #8
-	strd	r4, [r1], #8
-	subs	r0, #0x01
-	bne	alloc
-	/* Drain pending loads and stores */
-	mcr	p15, 0, r0, c7, c10, 4
-	mov	r2, #0x00
-	mcr	p15, 0, r2, c9, c2, 0
-	CPWAIT	r0
-
-	/* Jump to 0x0 ( + offset) if running from SRAM */
-	adr	r0, zerojmp
-	bic	r0, #0x5c000000
-	mov	pc, r0
-zerojmp:
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+	bl  cpu_init_crit
+#endif
 
 /* Set stackpointer in internal RAM to call board_init_f */
 call_board_init_f:
 	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
 	bic	sp, sp, #7 /* 8-byte alignment for ABI compliance */
-	ldr	r0,=0x00000000
+	ldr	r0, =0x00000000
 	bl	board_init_f
 
 /*------------------------------------------------------------------------------*/
-
+#ifndef CONFIG_SPL_BUILD
 /*
  * void relocate_code (addr_sp, gd, addr_moni)
  *
@@ -254,13 +186,11 @@ stack_setup:
 	ldr	r3, _bss_start_ofs
 	add	r2, r0, r3		/* r2 <- source end address	    */
 
-	stmfd sp!, {r0-r12}
 copy_loop:
-	ldmia	r0!, {r3-r5, r7-r11}	/* copy from source address [r0]    */
-	stmia	r1!, {r3-r5, r7-r11}	/* copy to   target address [r1]    */
+	ldmia	r0!, {r9-r10}		/* copy from source address [r0]    */
+	stmia	r1!, {r9-r10}		/* copy to   target address [r1]    */
 	cmp	r0, r2			/* until source end address [r2]    */
 	blo	copy_loop
-	ldmfd sp!, {r0-r12}
 
 #ifndef CONFIG_SPL_BUILD
 	/*
@@ -275,13 +205,13 @@ copy_loop:
 	ldr	r3, _rel_dyn_end_ofs	/* r3 <- rel dyn end ofs */
 	add	r3, r3, r0		/* r3 <- rel dyn end in FLASH */
 fixloop:
-	ldr	r0, [r2]	/* r0 <- location to fix up, IN FLASH! */
-	add	r0, r9		/* r0 <- location to fix up in RAM */
+	ldr	r0, [r2]		/* r0 <- location to fix up, IN FLASH! */
+	add	r0, r0, r9		/* r0 <- location to fix up in RAM */
 	ldr	r1, [r2, #4]
 	and	r7, r1, #0xff
-	cmp	r7, #23		/* relative fixup? */
+	cmp	r7, #23			/* relative fixup? */
 	beq	fixrel
-	cmp	r7, #2		/* absolute fixup? */
+	cmp	r7, #2			/* absolute fixup? */
 	beq	fixabs
 	/* ignore unknown type of fixup */
 	b	fixnext
@@ -298,10 +228,10 @@ fixrel:
 	add	r1, r1, r9
 fixnext:
 	str	r1, [r0]
-	add	r2, r2, #8	/* each rel.dyn entry is 8 bytes */
+	add	r2, r2, #8		/* each rel.dyn entry is 8 bytes */
 	cmp	r2, r3
 	blo	fixloop
-#endif	/* #ifndef CONFIG_SPL_BUILD */
+#endif
 
 clear_bss:
 #ifndef CONFIG_SPL_BUILD
@@ -322,15 +252,16 @@ clbss_l:str	r2, [r0]		/* clear loop...		    */
  * We are done. Do not return, instead branch to second part of board
  * initialization, now running from RAM.
  */
-#ifdef CONFIG_ONENAND_IPL
-	ldr     r0, _start_oneboot_ofs
+#ifdef CONFIG_ONENAND_SPL
+	ldr     r0, _onenand_boot_ofs
 	mov	pc, r0
 
-_start_oneboot_ofs
-	: .word start_oneboot
+_onenand_boot_ofs:
+	.word onenand_boot
 #else
+jump_2_ram:
 	ldr	r0, _board_init_r_ofs
-	adr	r1, _start
+	ldr     r1, _TEXT_BASE
 	add	lr, r0, r1
 	add	lr, lr, r9
 	/* setup parameters for board_init_r */
@@ -341,7 +272,7 @@ _start_oneboot_ofs
 
 _board_init_r_ofs:
 	.word board_init_r - _start
-#endif	/* CONFIG_ONENAND_IPL */
+#endif
 
 _rel_dyn_start_ofs:
 	.word __rel_dyn_start - _start
@@ -349,43 +280,50 @@ _rel_dyn_end_ofs:
 	.word __rel_dyn_end - _start
 _dynsym_start_ofs:
 	.word __dynsym_start - _start
-
-#else /* CONFIG_SPL_BUILD */
-
-/****************************************************************************/
-/*									    */
-/* the actual reset code for OneNAND IPL				    */
-/*									    */
-/****************************************************************************/
-
-#ifndef	CONFIG_PXA27X
-#error OneNAND IPL is not supported on PXA25x and 26x due to lack of SRAM
 #endif
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+cpu_init_crit:
+	/*
+	 * flush v4 I/D caches
+	 */
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7, 0	/* Invalidate I+D+BTB caches */
+	mcr	p15, 0, r0, c8, c7, 0	/* Invalidate Unified TLB */
 
-reset:
-	/* Set CPU to SVC32 mode */
-	mrs	r0,cpsr
-	bic	r0,r0,#0x1f
-	orr	r0,r0,#0x13
-	msr	cpsr,r0
-
-	/* Point stack@the end of SRAM and leave 32 words for abort-stack */
-	ldr	sp, =0x5c03ff80
-
-	/* Start OneNAND IPL */
-	ldr	pc, =start_oneboot
+	/*
+	 * disable MMU stuff and caches
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS)
+	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM)
+	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align
+	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache
+	mcr	p15, 0, r0, c1, c0, 0
 
-#endif /* CONFIG_SPL_BUILD */
+	mov	pc, lr		/* back to my caller */
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
 
 #ifndef CONFIG_SPL_BUILD
-/****************************************************************************/
-/*									    */
-/* Interrupt handling							    */
-/*									    */
-/****************************************************************************/
-
-/* IRQ stack frame							    */
-
+/*
+ *************************************************************************
+ *
+ * Interrupt handling
+ *
+ *************************************************************************
+ */
+@
+@ IRQ stack frame.
+@
 #define S_FRAME_SIZE	72
 
 #define S_OLD_R0	68
@@ -409,37 +347,36 @@ reset:
 #define S_R0		0
 
 #define MODE_SVC 0x13
+#define I_BIT	 0x80
 
-	/* use bad_save_user_regs for abort/prefetch/undef/swi ...	    */
+/*
+ * use bad_save_user_regs for abort/prefetch/undef/swi ...
+ * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
+ */
 
 	.macro	bad_save_user_regs
-	sub	sp, sp, #S_FRAME_SIZE
-	stmia	sp, {r0 - r12}			/* Calling r0-r12	    */
-	add	r8, sp, #S_PC
+	sub	sp, sp, #S_FRAME_SIZE		@ carve out a frame on current user stack
+	stmia	sp, {r0 - r12}			@ Save user registers (now in svc mode) r0-r12
 
-	ldr	r2, IRQ_STACK_START_IN
-	ldmia	r2, {r2 - r4}			/* get pc, cpsr, old_r0	    */
-	add	r0, sp, #S_FRAME_SIZE		/* restore sp_SVC	    */
+	ldr	r2, IRQ_STACK_START_IN		@ set base 2 words into abort stack
+	ldmia	r2, {r2 - r3}			@ get values for "aborted" pc and cpsr (into parm regs)
+	add	r0, sp, #S_FRAME_SIZE		@ grab pointer to old stack
 
 	add	r5, sp, #S_SP
 	mov	r1, lr
-	stmia	r5, {r0 - r4}			/* save sp_SVC, lr_SVC, pc, cpsr, old_r */
-	mov	r0, sp
+	stmia	r5, {r0 - r3}			@ save sp_SVC, lr_SVC, pc, cpsr
+	mov	r0, sp				@ save current stack into r0 (param register)
 	.endm
 
-
-	/* use irq_save_user_regs / irq_restore_user_regs for		     */
-	/* IRQ/FIQ handling						     */
-
 	.macro	irq_save_user_regs
 	sub	sp, sp, #S_FRAME_SIZE
-	stmia	sp, {r0 - r12}			/* Calling r0-r12	     */
-	add	r8, sp, #S_PC
-	stmdb	r8, {sp, lr}^			/* Calling SP, LR	     */
-	str	lr, [r8, #0]			/* Save calling PC	     */
+	stmia	sp, {r0 - r12}			@ Calling r0-r12
+	add	r8, sp, #S_PC			@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
+	stmdb	r8, {sp, lr}^			@ Calling SP, LR
+	str	lr, [r8, #0]			@ Save calling PC
 	mrs	r6, spsr
-	str	r6, [r8, #4]			/* Save CPSR		     */
-	str	r0, [r8, #8]			/* Save OLD_R0		     */
+	str	r6, [r8, #4]			@ Save CPSR
+	str	r0, [r8, #8]			@ Save OLD_R0
 	mov	r0, sp
 	.endm
 
@@ -452,16 +389,28 @@ reset:
 	.endm
 
 	.macro get_bad_stack
-	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
+	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack (enter in banked mode)
 
-	str	lr, [r13]			@ save caller lr / spsr
-	mrs	lr, spsr
-	str	lr, [r13, #4]
+	str	lr, [r13]			@ save caller lr in position 0 of saved stack
+	mrs	lr, spsr			@ get the spsr
+	str	lr, [r13, #4]			@ save spsr in position 1 of saved stack
 
 	mov	r13, #MODE_SVC			@ prepare SVC-Mode
-	msr	spsr_c, r13
-	mov	lr, pc
-	movs	pc, lr
+	@ msr	spsr_c, r13
+	msr	spsr, r13			@ switch modes, make sure moves will execute
+	mov	lr, pc				@ capture return pc
+	movs	pc, lr				@ jump to next instruction & switch modes.
+	.endm
+
+	.macro get_bad_stack_swi
+	sub	r13, r13, #4			@ space on current stack for scratch reg.
+	str	r0, [r13]			@ save R0's value.
+	ldr	r0, IRQ_STACK_START_IN		@ get data regions start
+	str	lr, [r0]			@ save caller lr in position 0 of saved stack
+	mrs	r0, spsr			@ get the spsr
+	str	lr, [r0, #4]			@ save spsr in position 1 of saved stack
+	ldr	r0, [r13]			@ restore r0
+	add	r13, r13, #4			@ pop stack entry
 	.endm
 
 	.macro get_irq_stack			@ setup IRQ stack
@@ -471,21 +420,17 @@ reset:
 	.macro get_fiq_stack			@ setup FIQ stack
 	ldr	sp, FIQ_STACK_START
 	.endm
-#endif	/* CONFIG_SPL_BUILD
-
-
-/****************************************************************************/
-/*									    */
-/* exception handlers							    */
-/*									    */
-/****************************************************************************/
+#endif	/* CONFIG_SPL_BUILD */
 
+/*
+ * exception handlers
+ */
 #ifdef CONFIG_SPL_BUILD
 	.align	5
 do_hang:
-	ldr	sp, _TEXT_BASE			/* use 32 words abort stack */
+	ldr	sp, _TEXT_BASE			/* use 32 words about stack */
 	bl	hang				/* hang and never return */
-#else
+#else	/* !CONFIG_SPL_BUILD */
 	.align	5
 undefined_instruction:
 	get_bad_stack
@@ -494,7 +439,7 @@ undefined_instruction:
 
 	.align	5
 software_interrupt:
-	get_bad_stack
+	get_bad_stack_swi
 	bad_save_user_regs
 	bl	do_software_interrupt
 
@@ -528,11 +473,12 @@ irq:
 	.align	5
 fiq:
 	get_fiq_stack
-	irq_save_user_regs		/* someone ought to write a more    */
-	bl	do_fiq			/* effiction fiq_save_user_regs	    */
+	/* someone ought to write a more effiction fiq_save_user_regs */
+	irq_save_user_regs
+	bl	do_fiq
 	irq_restore_user_regs
 
-#else /* !CONFIG_USE_IRQ */
+#else
 
 	.align	5
 irq:
@@ -545,63 +491,7 @@ fiq:
 	get_bad_stack
 	bad_save_user_regs
 	bl	do_fiq
-#endif	/* CONFIG_SPL_BUILD */
-#endif /* CONFIG_USE_IRQ */
-
-/****************************************************************************/
-/*									    */
-/* Reset function: the PXA250 doesn't have a reset function, so we have to  */
-/* perform a watchdog timeout for a soft reset.				    */
-/*									    */
-/****************************************************************************/
-/* Operating System Timer */
-.align	5
-.globl reset_cpu
-
-	/* FIXME: this code is PXA250 specific. How is this handled on	    */
-	/*	  other XScale processors?				    */
-
-reset_cpu:
-
-	/* We set OWE:WME (watchdog enable) and wait until timeout happens  */
 
-	ldr	r0, =OWER
-	ldr	r1, [r0]
-	orr	r1, r1, #0x0001			/* bit0: WME		    */
-	str	r1, [r0]
-
-	/* OS timer does only wrap every 1165 seconds, so we have to set    */
-	/* the match register as well.					    */
-
-	ldr	r0, =OSCR
-	ldr	r1, [r0]			/* read OS timer	    */
-	add	r1, r1, #0x800			/* let OSMR3 match after    */
-	add	r1, r1, #0x800			/* 4096*(1/3.6864MHz)=1ms   */
-	ldr	r0, =OSMR3
-	str	r1, [r0]
-
-reset_endless:
-
-	b	reset_endless
-
-#ifndef CONFIG_SPL_BUILD
-.section .mmudata, "a"
-	.align	14
-	.globl	mmu_table
-mmu_table:
-	/* 0x00000000 - 0xa0000000 : 1:1, uncached mapping */
-	.set	__base, 0
-	.rept	0xa00
-	.word	(__base << 20) | 0xc12
-	.set	__base, __base + 1
-	.endr
-
-	/* 0xa0000000 - 0xa0100000 : 1:1, cached mapping */
-	.word	(0xa00 << 20) | 0x1c1e
-
-	.set	__base, 0xa01
-	.rept	0x1000 - 0xa01
-	.word	(__base << 20) | 0xc12
-	.set	__base, __base + 1
-	.endr
+#endif
+	.align 5
 #endif	/* CONFIG_SPL_BUILD */
-- 
1.7.6.3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 3/4 V2] OneNAND: Add simple OneNAND SPL
  2011-10-31 13:23 ` [U-Boot] [PATCH 3/4] OneNAND: Add simple OneNAND SPL Marek Vasut
  2011-10-31 23:15   ` Scott Wood
@ 2011-11-01 22:54   ` Marek Vasut
  2011-11-02 22:41     ` Scott Wood
  2011-11-03  1:55     ` [U-Boot] [PATCH 3/4 V3] " Marek Vasut
  1 sibling, 2 replies; 38+ messages in thread
From: Marek Vasut @ 2011-11-01 22:54 UTC (permalink / raw)
  To: u-boot

This introduces small OneNAND loader, fitting into 1kB of space (smallest
possible OneNAND RAM size). Some devices equipped with such crappy chips will
use this.

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Scott Wood <scottwood@freescale.com>
---
 drivers/mtd/onenand/Makefile      |    4 +
 drivers/mtd/onenand/onenand_spl.c |  151 +++++++++++++++++++++++++++++++++++++
 include/onenand_uboot.h           |    8 ++
 spl/Makefile                      |    1 +
 4 files changed, 164 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/onenand/onenand_spl.c

V2: Introduce spl_onenand_load_image() to load data from OneNAND in SPL

diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
index b984bd4..b090d40 100644
--- a/drivers/mtd/onenand/Makefile
+++ b/drivers/mtd/onenand/Makefile
@@ -25,8 +25,12 @@ include $(TOPDIR)/config.mk
 
 LIB	:= $(obj)libonenand.o
 
+ifndef	CONFIG_SPL_BUILD
 COBJS-$(CONFIG_CMD_ONENAND)	:= onenand_uboot.o onenand_base.o onenand_bbt.o
 COBJS-$(CONFIG_SAMSUNG_ONENAND)	+= samsung.o
+else
+COBJS-y				:= onenand_spl.o
+endif
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/mtd/onenand/onenand_spl.c b/drivers/mtd/onenand/onenand_spl.c
new file mode 100644
index 0000000..d887d20
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_spl.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on code:
+ *	Copyright (C) 2005-2009 Samsung Electronics
+ *	Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * 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>
+#include <asm/io.h>
+#include <linux/mtd/onenand_regs.h>
+#include <onenand_uboot.h>
+
+struct spl_onenand_data {
+	uint32_t	pagesize;
+	uint32_t	erasesize;
+};
+
+#define ONENAND_PAGES_PER_BLOCK			64
+#define onenand_block_address(block)		(block)
+#define onenand_sector_address(page)		(page << 2)
+#define onenand_buffer_address()		((1 << 3) << 8)
+#define onenand_bufferram_address(block)	(0)
+
+static inline uint16_t onenand_readw(uint32_t addr)
+{
+	return readw(CONFIG_SYS_ONENAND_BASE + addr);
+}
+
+static inline void onenand_writew(uint16_t value, uint32_t addr)
+{
+	writew(value, CONFIG_SYS_ONENAND_BASE + addr);
+}
+
+static void spl_onenand_get_geometry(struct spl_onenand_data *data)
+{
+	uint32_t tmp;
+	uint32_t dev_id, density;
+
+	/* Default geometry -- 2048b page, 128k erase block. */
+	data->pagesize = 2048;
+	data->erasesize = 0x20000;
+
+	tmp = onenand_readw(ONENAND_REG_TECHNOLOGY);
+	if (tmp)
+		goto dev_4k;
+
+	dev_id = onenand_readw(ONENAND_REG_DEVICE_ID);
+	density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
+	density &= ONENAND_DEVICE_DENSITY_MASK;
+
+	if (density < ONENAND_DEVICE_DENSITY_4Gb)
+		return;
+
+	if (dev_id & ONENAND_DEVICE_IS_DDP)
+		return;
+
+	/* 4k device geometry -- 4096b page, 256k erase block. */
+dev_4k:
+	data->pagesize = 4096;
+	data->erasesize = 0x40000;
+}
+
+static int spl_onenand_read_page(uint32_t block, uint32_t page,
+				uint32_t *buf, int pagesize)
+{
+	const uint32_t addr = CONFIG_SYS_ONENAND_BASE + ONENAND_DATARAM;
+	uint32_t offset;
+
+	onenand_writew(onenand_block_address(block),
+			ONENAND_REG_START_ADDRESS1);
+
+	onenand_writew(onenand_bufferram_address(block),
+			ONENAND_REG_START_ADDRESS2);
+
+	onenand_writew(onenand_sector_address(page),
+			ONENAND_REG_START_ADDRESS8);
+
+	onenand_writew(onenand_buffer_address(),
+			ONENAND_REG_START_BUFFER);
+
+	onenand_writew(ONENAND_INT_CLEAR, ONENAND_REG_INTERRUPT);
+
+	onenand_writew(ONENAND_CMD_READ, ONENAND_REG_COMMAND);
+
+	while (!(onenand_readw(ONENAND_REG_INTERRUPT) & ONENAND_INT_READ))
+		continue;
+
+	/* Check for invalid block mark */
+	if (page < 2 && (onenand_readw(ONENAND_SPARERAM) != 0xffff))
+		return 1;
+
+	for (offset = 0; offset < pagesize; offset += 4)
+		buf[offset / 4] = readl(addr + offset);
+
+	return 0;
+}
+
+int spl_onenand_load_image(uint32_t dst, uint32_t offset, uint32_t len)
+{
+	uint32_t *addr = (uint32_t *)dst;
+	struct spl_onenand_data data;
+	uint32_t total_pages;
+	uint32_t block;
+	uint32_t page, rpage;
+	int ret, err = 0;
+
+	spl_onenand_get_geometry(&data);
+
+	/* The page can be either 2k or 4k, avoid using DIV_ROUND_UP. */
+	if (data.pagesize == 2048) {
+		total_pages = len / 2048;
+		page = offset / 2048;
+		total_pages += !!(len & 2047);
+	} else if (data.pagesize == 4096) {
+		total_pages = len / 4096;
+		page = offset / 4096;
+		total_pages += !!(len & 4095);
+	}
+
+	for (; page <= total_pages; page++) {
+		block = page / ONENAND_PAGES_PER_BLOCK;
+		rpage = page & (ONENAND_PAGES_PER_BLOCK - 1);
+		ret = spl_onenand_read_page(block, rpage, addr, data.pagesize);
+		if (ret) {
+			total_pages++;
+			err |= 1;
+		} else
+			addr += data.pagesize / 4;
+	}
+
+	return err;
+}
diff --git a/include/onenand_uboot.h b/include/onenand_uboot.h
index 92279d5..fcb50ff 100644
--- a/include/onenand_uboot.h
+++ b/include/onenand_uboot.h
@@ -16,6 +16,8 @@
 
 #include <linux/types.h>
 
+#ifndef	CONFIG_SPL_BUILD
+
 /* Forward declarations */
 struct mtd_info;
 struct mtd_oob_ops;
@@ -52,4 +54,10 @@ extern int flexonenand_set_boundary(struct mtd_info *mtd, int die,
 extern void s3c64xx_onenand_init(struct mtd_info *);
 extern void s3c64xx_set_width_regs(struct onenand_chip *);
 
+#else
+
+int spl_onenand_load_image(uint32_t dst, uint32_t offset, uint32_t len);
+
+#endif
+
 #endif /* __UBOOT_ONENAND_H */
diff --git a/spl/Makefile b/spl/Makefile
index d4d754d..b4001bf 100644
--- a/spl/Makefile
+++ b/spl/Makefile
@@ -54,6 +54,7 @@ LIBS-$(CONFIG_SPL_FAT_SUPPORT) += fs/fat/libfat.o
 LIBS-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/libgeneric.o
 LIBS-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/libpower.o
 LIBS-$(CONFIG_SPL_NAND_SUPPORT) += drivers/mtd/nand/libnand.o
+LIBS-$(CONFIG_SPL_ONENAND_SUPPORT) += drivers/mtd/onenand/libonenand.o
 LIBS-$(CONFIG_SPL_DMA_SUPPORT) += drivers/dma/libdma.o
 
 ifeq ($(SOC),omap3)
-- 
1.7.6.3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4 V2] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-10-31 13:23 ` [U-Boot] [PATCH 4/4] PXA: Adapt Voipac PXA270 to " Marek Vasut
  2011-10-31 23:03   ` Scott Wood
@ 2011-11-01 22:54   ` Marek Vasut
  2011-11-02 22:23     ` Scott Wood
  2011-11-03  1:56     ` [U-Boot] [PATCH 4/4 V3] " Marek Vasut
  1 sibling, 2 replies; 38+ messages in thread
From: Marek Vasut @ 2011-11-01 22:54 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
---
 board/vpac270/Makefile       |    4 ++
 board/vpac270/onenand.c      |   66 ++++++++++++++++++++++++++++
 board/vpac270/u-boot-spl.lds |   97 ++++++++++++++++++++++++++++++++++++++++++
 board/vpac270/vpac270.c      |    2 +
 include/configs/vpac270.h    |   25 +++++++++--
 5 files changed, 189 insertions(+), 5 deletions(-)
 create mode 100644 board/vpac270/onenand.c
 create mode 100644 board/vpac270/u-boot-spl.lds

V2: Add missing u-boot-spl.lds, convert bitshifts to division,
    convert to spl_onenand_load_image()

diff --git a/board/vpac270/Makefile b/board/vpac270/Makefile
index b5c60fd..5967055 100644
--- a/board/vpac270/Makefile
+++ b/board/vpac270/Makefile
@@ -23,7 +23,11 @@ include $(TOPDIR)/config.mk
 
 LIB	= $(obj)lib$(BOARD).o
 
+ifndef	CONFIG_SPL_BUILD
 COBJS	:= vpac270.o
+else
+COBJS	:= onenand.o
+endif
 
 SRCS	:= $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
diff --git a/board/vpac270/onenand.c b/board/vpac270/onenand.c
new file mode 100644
index 0000000..5aea774
--- /dev/null
+++ b/board/vpac270/onenand.c
@@ -0,0 +1,66 @@
+/*
+ * Voipac PXA270 OneNAND SPL
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * 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>
+#include <config.h>
+#include <asm/io.h>
+#include <onenand_uboot.h>
+
+extern void pxa_dram_init(void);
+
+inline void board_init_f(unsigned long unused)
+{
+	extern uint32_t _end;
+	uint32_t tmp;
+
+	asm volatile("mov %0, pc" : "=r"(tmp));
+	tmp >>= 24;
+
+	/* The code runs from OneNAND RAM, copy SPL to SRAM and execute it. */
+	if (tmp == 0) {
+		tmp = (uint32_t)&_end - CONFIG_SPL_TEXT_BASE;
+		spl_onenand_load_image(CONFIG_SPL_TEXT_BASE, 0, tmp);
+		asm volatile("mov pc, %0" : : "r"(CONFIG_SPL_TEXT_BASE));
+	}
+
+	/* Hereby, the code runs from (S)RAM, copy U-Boot and execute it. */
+	arch_cpu_init();
+	pxa_dram_init();
+	spl_onenand_load_image(CONFIG_SYS_TEXT_BASE,
+				CONFIG_SPL_ONENAND_LOAD_ADDR,
+				CONFIG_SPL_ONENAND_LOAD_SIZE);
+	asm volatile("mov pc, %0" : : "r"(CONFIG_SYS_TEXT_BASE));
+
+	for (;;)
+		;
+}
+
+void __attribute__((noreturn)) hang(void)
+{
+	for (;;)
+		;
+}
+
+void icache_disable(void) {}
+void dcache_disable(void) {}
diff --git a/board/vpac270/u-boot-spl.lds b/board/vpac270/u-boot-spl.lds
new file mode 100644
index 0000000..75acdcd
--- /dev/null
+++ b/board/vpac270/u-boot-spl.lds
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * January 2004 - Changed to support H4 device
+ * Copyright (c) 2004-2008 Texas Instruments
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@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
+{
+	. = CONFIG_SPL_TEXT_BASE;
+	.text.0	:
+	{
+		arch/arm/cpu/pxa/start.o		(.text*)
+		board/vpac270/libvpac270.o		(.text*)
+		drivers/mtd/onenand/libonenand.o	(.text*)
+	}
+
+
+	/* Start of the rest of the SPL */
+	. = CONFIG_SPL_TEXT_BASE + 0x800;
+
+	.text.1	:
+	{
+		*(.text*)
+	}
+
+	. = ALIGN(4);
+	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+	. = ALIGN(4);
+	.data : {
+		*(.data)
+	}
+
+	. = ALIGN(4);
+	__u_boot_cmd_start = .;
+	.u_boot_cmd : { *(.u_boot_cmd) }
+	__u_boot_cmd_end = .;
+
+	. = ALIGN(4);
+
+	.rel.dyn : {
+		__rel_dyn_start = .;
+		*(.rel*)
+		__rel_dyn_end = .;
+	}
+
+	.dynsym : {
+		__dynsym_start = .;
+		*(.dynsym)
+	}
+
+	. = ALIGN(0x800);
+
+	_end = .;
+
+	.bss __rel_dyn_start (OVERLAY) : {
+		__bss_start = .;
+		*(.bss)
+		 . = ALIGN(4);
+		__bss_end__ = .;
+	}
+
+	/DISCARD/ : { *(.bss*) }
+	/DISCARD/ : { *(.dynstr*) }
+	/DISCARD/ : { *(.dynsym*) }
+	/DISCARD/ : { *(.dynamic*) }
+	/DISCARD/ : { *(.hash*) }
+	/DISCARD/ : { *(.plt*) }
+	/DISCARD/ : { *(.interp*) }
+	/DISCARD/ : { *(.gnu*) }
+}
diff --git a/board/vpac270/vpac270.c b/board/vpac270/vpac270.c
index cf8e7b6..d90a859 100644
--- a/board/vpac270/vpac270.c
+++ b/board/vpac270/vpac270.c
@@ -57,7 +57,9 @@ struct serial_device *default_serial_console(void)
 extern void pxa_dram_init(void);
 int dram_init(void)
 {
+#ifndef	CONFIG_ONENAND
 	pxa_dram_init();
+#endif
 	gd->ram_size = PHYS_SDRAM_1_SIZE;
 	return 0;
 }
diff --git a/include/configs/vpac270.h b/include/configs/vpac270.h
index dd68c66..8accebf 100644
--- a/include/configs/vpac270.h
+++ b/include/configs/vpac270.h
@@ -27,7 +27,17 @@
  */
 #define	CONFIG_PXA27X		1	/* Marvell PXA270 CPU */
 #define	CONFIG_VPAC270		1	/* Voipac PXA270 board */
-#define	CONFIG_SYS_TEXT_BASE	0x0
+#define	CONFIG_SYS_TEXT_BASE	0xa0000000
+
+#ifdef	CONFIG_ONENAND
+#define	CONFIG_SPL
+#define	CONFIG_SPL_ONENAND_SUPPORT
+#define	CONFIG_SPL_ONENAND_LOAD_ADDR	0x2000
+#define	CONFIG_SPL_ONENAND_LOAD_SIZE	\
+	(512 * 1024 - CONFIG_SPL_ONENAND_LOAD_ADDR)
+#define	CONFIG_SPL_TEXT_BASE	0x5c000000
+#define	CONFIG_SPL_LDSCRIPT	"board/vpac270/u-boot-spl.lds"
+#endif
 
 /*
  * Environment settings
@@ -46,12 +56,19 @@
 		"bootm 0xa4000000; "					\
 	"fi; "								\
 	"bootm 0x60000;"
+
+#define	CONFIG_EXTRA_ENV_SETTINGS					\
+	"update_onenand="						\
+		"onenand erase 0x0 0x80000 ; "				\
+		"onenand write 0xa0000000 0x0 0x80000"
+
 #define	CONFIG_BOOTARGS			"console=tty0 console=ttyS0,115200"
 #define	CONFIG_TIMESTAMP
 #define	CONFIG_BOOTDELAY		2	/* Autoboot delay */
 #define	CONFIG_CMDLINE_TAG
 #define	CONFIG_SETUP_MEMORY_TAGS
 #define	CONFIG_LZMA			/* LZMA compression support */
+#define	CONFIG_OF_LIBFDT
 
 /*
  * Serial Console Configuration
@@ -180,16 +197,14 @@
 #define	CONFIG_SYS_MEMTEST_END		0xa0800000	/* 4 ... 8 MB in DRAM */
 
 #define	CONFIG_SYS_LOAD_ADDR		PHYS_SDRAM_1
-#define	CONFIG_SYS_IPL_LOAD_ADDR	(0x5c000000)
 #define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
-#define	CONFIG_SYS_INIT_SP_ADDR		\
-	(PHYS_SDRAM_1 + GENERATED_GBL_DATA_SIZE + 2048)
+#define	CONFIG_SYS_INIT_SP_ADDR		0x5c010000
 
 /*
  * NOR FLASH
  */
 #define	CONFIG_SYS_MONITOR_BASE		0x0
-#define	CONFIG_SYS_MONITOR_LEN		0x40000
+#define	CONFIG_SYS_MONITOR_LEN		0x80000
 #define	CONFIG_ENV_ADDR			\
 			(CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN)
 #define	CONFIG_ENV_SIZE			0x4000
-- 
1.7.6.3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 2/4] PXA: Rework start.S to be closer to other ARMs
  2011-10-31 13:23 ` [U-Boot] [PATCH 2/4] PXA: Rework start.S to be closer to other ARMs Marek Vasut
  2011-11-01 22:53   ` [U-Boot] [PATCH 2/4 V2] " Marek Vasut
@ 2011-11-02  9:01   ` Stefan Herbrechtsmeier
  2011-11-02 10:25     ` Marek Vasut
  1 sibling, 1 reply; 38+ messages in thread
From: Stefan Herbrechtsmeier @ 2011-11-02  9:01 UTC (permalink / raw)
  To: u-boot

Am 31.10.2011 14:23, schrieb Marek Vasut:
> The start.S on PXA was very obscure. This reworks it back to be close to arm1136
> start.S and others.
>
> Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
> Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
> ---
>  arch/arm/cpu/pxa/cpu.c   |   16 ++
>  arch/arm/cpu/pxa/start.S |  382 ++++++++++++++++-----------------------------
>  2 files changed, 152 insertions(+), 246 deletions(-)
Hi Marek,

if I understand your code right, you change the initial memory from
cache to SRAM,
but this is not available on the pxa255. Do you plan to drop the pxa255
support?

Do you plan to update the pxa boards config?

I assume that I can drop my patch to fix the relocation on pxa.

Regards,
    Stefan

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 2/4] PXA: Rework start.S to be closer to other ARMs
  2011-11-02  9:01   ` [U-Boot] [PATCH 2/4] " Stefan Herbrechtsmeier
@ 2011-11-02 10:25     ` Marek Vasut
  2011-11-02 10:53       ` Stefan Herbrechtsmeier
  0 siblings, 1 reply; 38+ messages in thread
From: Marek Vasut @ 2011-11-02 10:25 UTC (permalink / raw)
  To: u-boot

> Am 31.10.2011 14:23, schrieb Marek Vasut:
> > The start.S on PXA was very obscure. This reworks it back to be close to
> > arm1136 start.S and others.
> > 
> > Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
> > Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
> > ---
> > 
> >  arch/arm/cpu/pxa/cpu.c   |   16 ++
> >  arch/arm/cpu/pxa/start.S |  382
> >  ++++++++++++++++----------------------------- 2 files changed, 152
> >  insertions(+), 246 deletions(-)
> 
> Hi Marek,
> 
> if I understand your code right, you change the initial memory from
> cache to SRAM,
> but this is not available on the pxa255. Do you plan to drop the pxa255
> support?

No, you're right. I'll probably have to add a workaround for this issue for 
pxa25x and 26x. Damn.
> 
> Do you plan to update the pxa boards config?
> 
> I assume that I can drop my patch to fix the relocation on pxa.

Do you have any pxa250 board and are you willing to help with this patch?
> 
> Regards,
>     Stefan

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 2/4] PXA: Rework start.S to be closer to other ARMs
  2011-11-02 10:25     ` Marek Vasut
@ 2011-11-02 10:53       ` Stefan Herbrechtsmeier
  0 siblings, 0 replies; 38+ messages in thread
From: Stefan Herbrechtsmeier @ 2011-11-02 10:53 UTC (permalink / raw)
  To: u-boot

Am 02.11.2011 11:25, schrieb Marek Vasut:
>> Am 31.10.2011 14:23, schrieb Marek Vasut:
>>> The start.S on PXA was very obscure. This reworks it back to be close to
>>> arm1136 start.S and others.
>>>
>>> Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
>>> Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
>>> ---
>>>
>>>  arch/arm/cpu/pxa/cpu.c   |   16 ++
>>>  arch/arm/cpu/pxa/start.S |  382
>>>  ++++++++++++++++----------------------------- 2 files changed, 152
>>>  insertions(+), 246 deletions(-)
>> Hi Marek,
>>
>> if I understand your code right, you change the initial memory from
>> cache to SRAM,
>> but this is not available on the pxa255. Do you plan to drop the pxa255
>> support?
> No, you're right. I'll probably have to add a workaround for this issue for 
> pxa25x and 26x. Damn.
>> Do you plan to update the pxa boards config?
>>
>> I assume that I can drop my patch to fix the relocation on pxa.
> Do you have any pxa250 board and are you willing to help with this patch?
I have only my customised pxa270 board.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-11-01 22:44         ` Marek Vasut
@ 2011-11-02 22:18           ` Scott Wood
  0 siblings, 0 replies; 38+ messages in thread
From: Scott Wood @ 2011-11-02 22:18 UTC (permalink / raw)
  To: u-boot

On 11/01/2011 05:44 PM, Marek Vasut wrote:
>> On 11/01/2011 05:12 PM, Marek Vasut wrote:
>>>> On 10/31/2011 08:23 AM, Marek Vasut wrote:
>>>>> Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
>>>>> Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
>>>>> ---
>>>
>>> [...]
>>>
>>>>> +	for (page = 0; page <= total_pages; page++) {
>>>>> +		ret = spl_onenand_read_page(0, page, addr, data.pagesize);
>>>>> +		if (ret)
>>>>> +			total_pages++;
>>>>> +		else
>>>>> +			addr += data.pagesize;
>>>>> +	}
>>>>> +}
>>>>
>>>> You want to skip to the next block if spl_onenand_read_page() fails
>>>> (which can occur after you've already read some of the block).
>>>
>>> I want to skip to next page, not next block.
>>
>> That's not how we normally do things, and is not what the current
>> OneNAND IPL does.
>>
>> Bad block markers apply to the entire block -- unless this is a
>> difference I'm not aware of between NAND and OneNAND.
> 
> Well then it will fail reading the whole block and continue onwards ... it's a 
> bit slower like this.

It doesn't work like that.  The bad block marker is in the first page of
the block only (sometimes the second page can be used).  The bad block
marker is not placed on every page in the block, so if you continue to
subsequent pages it will not fail, but you won't be getting the data
you're expecting.

-Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4 V2] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-11-01 22:54   ` [U-Boot] [PATCH 4/4 V2] " Marek Vasut
@ 2011-11-02 22:23     ` Scott Wood
  2011-11-03  1:56     ` [U-Boot] [PATCH 4/4 V3] " Marek Vasut
  1 sibling, 0 replies; 38+ messages in thread
From: Scott Wood @ 2011-11-02 22:23 UTC (permalink / raw)
  To: u-boot

On 11/01/2011 05:54 PM, Marek Vasut wrote:
> +inline void board_init_f(unsigned long unused)

Drop the inline.

> +	/* Start of the rest of the SPL */
> +	. = CONFIG_SPL_TEXT_BASE + 0x800;
> +
> +	.text.1	:
> +	{
> +		*(.text*)
> +	}
> +
> +	. = ALIGN(4);
> +	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
> +
> +	. = ALIGN(4);
> +	.data : {
> +		*(.data)
> +	}
> +
> +	. = ALIGN(4);
> +	__u_boot_cmd_start = .;
> +	.u_boot_cmd : { *(.u_boot_cmd) }
> +	__u_boot_cmd_end = .;

Commands in an SPL?

-Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 3/4 V2] OneNAND: Add simple OneNAND SPL
  2011-11-01 22:54   ` [U-Boot] [PATCH 3/4 V2] " Marek Vasut
@ 2011-11-02 22:41     ` Scott Wood
  2011-11-03  0:15       ` Marek Vasut
  2011-11-03  1:55     ` [U-Boot] [PATCH 3/4 V3] " Marek Vasut
  1 sibling, 1 reply; 38+ messages in thread
From: Scott Wood @ 2011-11-02 22:41 UTC (permalink / raw)
  To: u-boot

On 11/01/2011 05:54 PM, Marek Vasut wrote:
> +static void spl_onenand_get_geometry(struct spl_onenand_data *data)
> +{
> +	uint32_t tmp;
> +	uint32_t dev_id, density;
> +
> +	/* Default geometry -- 2048b page, 128k erase block. */
> +	data->pagesize = 2048;
> +	data->erasesize = 0x20000;
> +
> +	tmp = onenand_readw(ONENAND_REG_TECHNOLOGY);
> +	if (tmp)
> +		goto dev_4k;
> +
> +	dev_id = onenand_readw(ONENAND_REG_DEVICE_ID);
> +	density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
> +	density &= ONENAND_DEVICE_DENSITY_MASK;
> +
> +	if (density < ONENAND_DEVICE_DENSITY_4Gb)
> +		return;
> +
> +	if (dev_id & ONENAND_DEVICE_IS_DDP)
> +		return;
> +
> +	/* 4k device geometry -- 4096b page, 256k erase block. */
> +dev_4k:
> +	data->pagesize = 4096;
> +	data->erasesize = 0x40000;
> +}

Drop the goto and "tmp" variable, just do:

	if (!onenand_readw(ONENAND_REG_TECHNOLOGY)) {
		dev_id = onenand_readw(ONENAND_REG_DEVICE_ID);
		density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
		density &= ONENAND_DEVICE_DENSITY_MASK;

		if (density < ONENAND_DEVICE_DENSITY_4Gb)
			return;

		if (dev_id & ONENAND_DEVICE_IS_DDP)
			return;
	}

> +int spl_onenand_load_image(uint32_t dst, uint32_t offset, uint32_t len)

Please use the same name and arguments as nand_spl_load_image() in
nand_spl_simple.c.

> +{
> +	uint32_t *addr = (uint32_t *)dst;

Why not pass it in as a pointer in the first place?  I know U-Boot is
unlkely to support being built as 64-bit any time soon, but why
introduce gratuitous 64-bit-uncleanliness?

> +	struct spl_onenand_data data;
> +	uint32_t total_pages;
> +	uint32_t block;
> +	uint32_t page, rpage;
> +	int ret, err = 0;
> +
> +	spl_onenand_get_geometry(&data);
> +
> +	/* The page can be either 2k or 4k, avoid using DIV_ROUND_UP. */
> +	if (data.pagesize == 2048) {
> +		total_pages = len / 2048;
> +		page = offset / 2048;
> +		total_pages += !!(len & 2047);
> +	} else if (data.pagesize == 4096) {
> +		total_pages = len / 4096;
> +		page = offset / 4096;
> +		total_pages += !!(len & 4095);
> +	}

What's wrong with DIV_ROUND_UP?  It should produce smaller code than
what you've done here...

> +	for (; page <= total_pages; page++) {
> +		block = page / ONENAND_PAGES_PER_BLOCK;
> +		rpage = page & (ONENAND_PAGES_PER_BLOCK - 1);
> +		ret = spl_onenand_read_page(block, rpage, addr, data.pagesize);
> +		if (ret) {
> +			total_pages++;
> +			err |= 1;
> +		} else
> +			addr += data.pagesize / 4;
> +	}

As discussed, please retain the existing block-skipping semantics.  And
if you do skip a block, that's not an error to be propagated upward (as
opposed to something like an uncorrectable ECC error).

If one side of an if statement requires braces, both sides should have them.

> diff --git a/include/onenand_uboot.h b/include/onenand_uboot.h
> index 92279d5..fcb50ff 100644
> --- a/include/onenand_uboot.h
> +++ b/include/onenand_uboot.h
> @@ -16,6 +16,8 @@
>  
>  #include <linux/types.h>
>  
> +#ifndef	CONFIG_SPL_BUILD
> +

Please use a space rather than a tab after #define, #ifndef, etc.

>  /* Forward declarations */
>  struct mtd_info;
>  struct mtd_oob_ops;
> @@ -52,4 +54,10 @@ extern int flexonenand_set_boundary(struct mtd_info *mtd, int die,
>  extern void s3c64xx_onenand_init(struct mtd_info *);
>  extern void s3c64xx_set_width_regs(struct onenand_chip *);
>  
> +#else
> +
> +int spl_onenand_load_image(uint32_t dst, uint32_t offset, uint32_t len);
> +
> +#endif

Why does this need to be ifdeffed at all?  We normally don't ifdef
header declarations.

-Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 3/4 V2] OneNAND: Add simple OneNAND SPL
  2011-11-02 22:41     ` Scott Wood
@ 2011-11-03  0:15       ` Marek Vasut
  2011-11-03  0:36         ` Kyungmin Park
  2011-11-03 16:19         ` Scott Wood
  0 siblings, 2 replies; 38+ messages in thread
From: Marek Vasut @ 2011-11-03  0:15 UTC (permalink / raw)
  To: u-boot

> On 11/01/2011 05:54 PM, Marek Vasut wrote:
> > +static void spl_onenand_get_geometry(struct spl_onenand_data *data)
> > +{
[...]

> > +	/* The page can be either 2k or 4k, avoid using DIV_ROUND_UP. */
> > +	if (data.pagesize == 2048) {
> > +		total_pages = len / 2048;
> > +		page = offset / 2048;
> > +		total_pages += !!(len & 2047);
> > +	} else if (data.pagesize == 4096) {
> > +		total_pages = len / 4096;
> > +		page = offset / 4096;
> > +		total_pages += !!(len & 4095);
> > +	}
> 
> What's wrong with DIV_ROUND_UP?  It should produce smaller code than
> what you've done here...

It pulls in aeabi_*div* functions, which won't fit into block 0 of Onenand.

> 
> > +	for (; page <= total_pages; page++) {
> > +		block = page / ONENAND_PAGES_PER_BLOCK;
> > +		rpage = page & (ONENAND_PAGES_PER_BLOCK - 1);
> > +		ret = spl_onenand_read_page(block, rpage, addr, data.pagesize);
> > +		if (ret) {
> > +			total_pages++;
> > +			err |= 1;
> > +		} else
> > +			addr += data.pagesize / 4;
> > +	}
> 
> As discussed, please retain the existing block-skipping semantics.  And
> if you do skip a block, that's not an error to be propagated upward (as
> opposed to something like an uncorrectable ECC error).
> 
> If one side of an if statement requires braces, both sides should have
> them.
> 
> > diff --git a/include/onenand_uboot.h b/include/onenand_uboot.h
> > index 92279d5..fcb50ff 100644
> > --- a/include/onenand_uboot.h
> > +++ b/include/onenand_uboot.h
> > @@ -16,6 +16,8 @@
> > 
> >  #include <linux/types.h>
> > 
> > +#ifndef	CONFIG_SPL_BUILD
> > +
> 
> Please use a space rather than a tab after #define, #ifndef, etc.
> 
> >  /* Forward declarations */
> >  struct mtd_info;
> >  struct mtd_oob_ops;
> > 
> > @@ -52,4 +54,10 @@ extern int flexonenand_set_boundary(struct mtd_info
> > *mtd, int die,
> > 
> >  extern void s3c64xx_onenand_init(struct mtd_info *);
> >  extern void s3c64xx_set_width_regs(struct onenand_chip *);
> > 
> > +#else
> > +
> > +int spl_onenand_load_image(uint32_t dst, uint32_t offset, uint32_t len);
> > +
> > +#endif
> 
> Why does this need to be ifdeffed at all?  We normally don't ifdef
> header declarations.
> 
> -Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 3/4 V2] OneNAND: Add simple OneNAND SPL
  2011-11-03  0:15       ` Marek Vasut
@ 2011-11-03  0:36         ` Kyungmin Park
  2011-11-03  0:59           ` Marek Vasut
  2011-11-03 16:19         ` Scott Wood
  1 sibling, 1 reply; 38+ messages in thread
From: Kyungmin Park @ 2011-11-03  0:36 UTC (permalink / raw)
  To: u-boot

Hi all,

Marek, did you see the onenand_ipl/onenand_read.c at u-boot? It's already
implemented and used for OneNAND boot.

How do you think migrate this file into generic SPL framework?

Thank you,
Kyungmin Park
 
-----Original Message-----
From: Marek Vasut [mailto:marek.vasut at gmail.com] 
Sent: Thursday, November 03, 2011 9:16 AM
To: Scott Wood
Cc: u-boot at lists.denx.de; Albert ARIBAUD; Kyungmin Park
Subject: Re: [PATCH 3/4 V2] OneNAND: Add simple OneNAND SPL

> On 11/01/2011 05:54 PM, Marek Vasut wrote:
> > +static void spl_onenand_get_geometry(struct spl_onenand_data *data)
> > +{
[...]

> > +	/* The page can be either 2k or 4k, avoid using DIV_ROUND_UP. */
> > +	if (data.pagesize == 2048) {
> > +		total_pages = len / 2048;
> > +		page = offset / 2048;
> > +		total_pages += !!(len & 2047);
> > +	} else if (data.pagesize == 4096) {
> > +		total_pages = len / 4096;
> > +		page = offset / 4096;
> > +		total_pages += !!(len & 4095);
> > +	}
> 
> What's wrong with DIV_ROUND_UP?  It should produce smaller code than
> what you've done here...

It pulls in aeabi_*div* functions, which won't fit into block 0 of Onenand.

> 
> > +	for (; page <= total_pages; page++) {
> > +		block = page / ONENAND_PAGES_PER_BLOCK;
> > +		rpage = page & (ONENAND_PAGES_PER_BLOCK - 1);
> > +		ret = spl_onenand_read_page(block, rpage, addr,
data.pagesize);
> > +		if (ret) {
> > +			total_pages++;
> > +			err |= 1;
> > +		} else
> > +			addr += data.pagesize / 4;
> > +	}
> 
> As discussed, please retain the existing block-skipping semantics.  And
> if you do skip a block, that's not an error to be propagated upward (as
> opposed to something like an uncorrectable ECC error).
> 
> If one side of an if statement requires braces, both sides should have
> them.
> 
> > diff --git a/include/onenand_uboot.h b/include/onenand_uboot.h
> > index 92279d5..fcb50ff 100644
> > --- a/include/onenand_uboot.h
> > +++ b/include/onenand_uboot.h
> > @@ -16,6 +16,8 @@
> > 
> >  #include <linux/types.h>
> > 
> > +#ifndef	CONFIG_SPL_BUILD
> > +
> 
> Please use a space rather than a tab after #define, #ifndef, etc.
> 
> >  /* Forward declarations */
> >  struct mtd_info;
> >  struct mtd_oob_ops;
> > 
> > @@ -52,4 +54,10 @@ extern int flexonenand_set_boundary(struct mtd_info
> > *mtd, int die,
> > 
> >  extern void s3c64xx_onenand_init(struct mtd_info *);
> >  extern void s3c64xx_set_width_regs(struct onenand_chip *);
> > 
> > +#else
> > +
> > +int spl_onenand_load_image(uint32_t dst, uint32_t offset, uint32_t
len);
> > +
> > +#endif
> 
> Why does this need to be ifdeffed at all?  We normally don't ifdef
> header declarations.
> 
> -Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 3/4 V2] OneNAND: Add simple OneNAND SPL
  2011-11-03  0:36         ` Kyungmin Park
@ 2011-11-03  0:59           ` Marek Vasut
  0 siblings, 0 replies; 38+ messages in thread
From: Marek Vasut @ 2011-11-03  0:59 UTC (permalink / raw)
  To: u-boot

> Hi all,
> 
> Marek, did you see the onenand_ipl/onenand_read.c at u-boot? It's already
> implemented and used for OneNAND boot.
> 
> How do you think migrate this file into generic SPL framework?

That's basically what I did, with a little polishing.
> 
> Thank you,
> Kyungmin Park

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 3/4 V3] OneNAND: Add simple OneNAND SPL
  2011-11-01 22:54   ` [U-Boot] [PATCH 3/4 V2] " Marek Vasut
  2011-11-02 22:41     ` Scott Wood
@ 2011-11-03  1:55     ` Marek Vasut
  2011-11-03 21:59       ` [U-Boot] [PATCH 3/4 V4] " Marek Vasut
  1 sibling, 1 reply; 38+ messages in thread
From: Marek Vasut @ 2011-11-03  1:55 UTC (permalink / raw)
  To: u-boot

This introduces small OneNAND loader, fitting into 1kB of space (smallest
possible OneNAND RAM size). Some devices equipped with such crappy chips will
use this.

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Scott Wood <scottwood@freescale.com>
---
 drivers/mtd/onenand/Makefile      |    4 +
 drivers/mtd/onenand/onenand_spl.c |  148 +++++++++++++++++++++++++++++++++++++
 include/onenand_uboot.h           |    3 +
 spl/Makefile                      |    1 +
 4 files changed, 156 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/onenand/onenand_spl.c

V2: Introduce spl_onenand_load_image() to load data from OneNAND in SPL
V3: Cleanup, align with nand_spl. Skip whole blocks.

diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
index b984bd4..b090d40 100644
--- a/drivers/mtd/onenand/Makefile
+++ b/drivers/mtd/onenand/Makefile
@@ -25,8 +25,12 @@ include $(TOPDIR)/config.mk
 
 LIB	:= $(obj)libonenand.o
 
+ifndef	CONFIG_SPL_BUILD
 COBJS-$(CONFIG_CMD_ONENAND)	:= onenand_uboot.o onenand_base.o onenand_bbt.o
 COBJS-$(CONFIG_SAMSUNG_ONENAND)	+= samsung.o
+else
+COBJS-y				:= onenand_spl.o
+endif
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/mtd/onenand/onenand_spl.c b/drivers/mtd/onenand/onenand_spl.c
new file mode 100644
index 0000000..4bf862e
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_spl.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on code:
+ *	Copyright (C) 2005-2009 Samsung Electronics
+ *	Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * 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>
+#include <asm/io.h>
+#include <linux/mtd/onenand_regs.h>
+#include <onenand_uboot.h>
+
+/*
+ * Device geometry:
+ * - 2048b page, 128k erase block.
+ * - 4096b page, 256k erase block.
+ */
+enum onenand_spl_pagesize {
+	PAGE_2K = 2048,
+	PAGE_4K = 4096,
+};
+
+#define ONENAND_PAGES_PER_BLOCK			64
+#define onenand_block_address(block)		(block)
+#define onenand_sector_address(page)		(page << 2)
+#define onenand_buffer_address()		((1 << 3) << 8)
+#define onenand_bufferram_address(block)	(0)
+
+static inline uint16_t onenand_readw(uint32_t addr)
+{
+	return readw(CONFIG_SYS_ONENAND_BASE + addr);
+}
+
+static inline void onenand_writew(uint16_t value, uint32_t addr)
+{
+	writew(value, CONFIG_SYS_ONENAND_BASE + addr);
+}
+
+static enum onenand_spl_pagesize onenand_spl_get_geometry(void)
+{
+	uint32_t dev_id, density;
+
+	if (!onenand_readw(ONENAND_REG_TECHNOLOGY)) {
+		dev_id = onenand_readw(ONENAND_REG_DEVICE_ID);
+		density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
+		density &= ONENAND_DEVICE_DENSITY_MASK;
+
+		if (density < ONENAND_DEVICE_DENSITY_4Gb)
+			return PAGE_2K;
+
+		if (dev_id & ONENAND_DEVICE_IS_DDP)
+			return PAGE_2K;
+	}
+
+	return PAGE_4K;
+}
+
+static int onenand_spl_read_page(uint32_t block, uint32_t page, uint32_t *buf,
+					enum onenand_spl_pagesize pagesize)
+{
+	const uint32_t addr = CONFIG_SYS_ONENAND_BASE + ONENAND_DATARAM;
+	uint32_t offset;
+
+	onenand_writew(onenand_block_address(block),
+			ONENAND_REG_START_ADDRESS1);
+
+	onenand_writew(onenand_bufferram_address(block),
+			ONENAND_REG_START_ADDRESS2);
+
+	onenand_writew(onenand_sector_address(page),
+			ONENAND_REG_START_ADDRESS8);
+
+	onenand_writew(onenand_buffer_address(),
+			ONENAND_REG_START_BUFFER);
+
+	onenand_writew(ONENAND_INT_CLEAR, ONENAND_REG_INTERRUPT);
+
+	onenand_writew(ONENAND_CMD_READ, ONENAND_REG_COMMAND);
+
+	while (!(onenand_readw(ONENAND_REG_INTERRUPT) & ONENAND_INT_READ))
+		continue;
+
+	/* Check for invalid block mark */
+	if (page < 2 && (onenand_readw(ONENAND_SPARERAM) != 0xffff))
+		return 1;
+
+	for (offset = 0; offset < pagesize; offset += 4)
+		buf[offset / 4] = readl(addr + offset);
+
+	return 0;
+}
+
+void onenand_spl_load_image(uint32_t offs, uint32_t size, void *dst)
+{
+	uint32_t *addr = (uint32_t *)dst;
+	uint32_t total_pages;
+	uint32_t block;
+	uint32_t page, rpage;
+	enum onenand_spl_pagesize pagesize;
+	int ret;
+
+	pagesize = onenand_spl_get_geometry();
+
+	/*
+	 * The page can be either 2k or 4k, avoid using DIV_ROUND_UP to avoid
+	 * pulling further unwanted functions into the SPL.
+	 */
+	if (pagesize == 2048) {
+		total_pages = size / 2048;
+		page = offs / 2048;
+		total_pages += !!(size & 2047);
+	} else {
+		total_pages = size / 4096;
+		page = offs / 4096;
+		total_pages += !!(size & 4095);
+	}
+
+	for (; page <= total_pages; page++) {
+		block = page / ONENAND_PAGES_PER_BLOCK;
+		rpage = page & (ONENAND_PAGES_PER_BLOCK - 1);
+		ret = onenand_spl_read_page(block, rpage, addr, pagesize);
+		if (ret) {
+			total_pages += ONENAND_PAGES_PER_BLOCK;
+			page += ONENAND_PAGES_PER_BLOCK - 1;
+		} else {
+			addr += pagesize / 4;
+		}
+	}
+}
diff --git a/include/onenand_uboot.h b/include/onenand_uboot.h
index 92279d5..f321d8a 100644
--- a/include/onenand_uboot.h
+++ b/include/onenand_uboot.h
@@ -52,4 +52,7 @@ extern int flexonenand_set_boundary(struct mtd_info *mtd, int die,
 extern void s3c64xx_onenand_init(struct mtd_info *);
 extern void s3c64xx_set_width_regs(struct onenand_chip *);
 
+/* SPL */
+void onenand_spl_load_image(uint32_t offs, uint32_t size, void *dst);
+
 #endif /* __UBOOT_ONENAND_H */
diff --git a/spl/Makefile b/spl/Makefile
index d4d754d..b4001bf 100644
--- a/spl/Makefile
+++ b/spl/Makefile
@@ -54,6 +54,7 @@ LIBS-$(CONFIG_SPL_FAT_SUPPORT) += fs/fat/libfat.o
 LIBS-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/libgeneric.o
 LIBS-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/libpower.o
 LIBS-$(CONFIG_SPL_NAND_SUPPORT) += drivers/mtd/nand/libnand.o
+LIBS-$(CONFIG_SPL_ONENAND_SUPPORT) += drivers/mtd/onenand/libonenand.o
 LIBS-$(CONFIG_SPL_DMA_SUPPORT) += drivers/dma/libdma.o
 
 ifeq ($(SOC),omap3)
-- 
1.7.6.3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4 V3] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-11-01 22:54   ` [U-Boot] [PATCH 4/4 V2] " Marek Vasut
  2011-11-02 22:23     ` Scott Wood
@ 2011-11-03  1:56     ` Marek Vasut
  2011-11-03 18:09       ` Scott Wood
  1 sibling, 1 reply; 38+ messages in thread
From: Marek Vasut @ 2011-11-03  1:56 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
---
 board/vpac270/Makefile       |    4 ++
 board/vpac270/onenand.c      |   66 ++++++++++++++++++++++++++++++
 board/vpac270/u-boot-spl.lds |   92 ++++++++++++++++++++++++++++++++++++++++++
 board/vpac270/vpac270.c      |    2 +
 include/configs/vpac270.h    |   25 +++++++++--
 5 files changed, 184 insertions(+), 5 deletions(-)
 create mode 100644 board/vpac270/onenand.c
 create mode 100644 board/vpac270/u-boot-spl.lds

V2: Add missing u-boot-spl.lds, convert bitshifts to division,
    convert to spl_onenand_load_image()
V3: Drop inlines, update linker script, update to conform new onenand_spl.

diff --git a/board/vpac270/Makefile b/board/vpac270/Makefile
index b5c60fd..5967055 100644
--- a/board/vpac270/Makefile
+++ b/board/vpac270/Makefile
@@ -23,7 +23,11 @@ include $(TOPDIR)/config.mk
 
 LIB	= $(obj)lib$(BOARD).o
 
+ifndef	CONFIG_SPL_BUILD
 COBJS	:= vpac270.o
+else
+COBJS	:= onenand.o
+endif
 
 SRCS	:= $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
diff --git a/board/vpac270/onenand.c b/board/vpac270/onenand.c
new file mode 100644
index 0000000..6a0a37b
--- /dev/null
+++ b/board/vpac270/onenand.c
@@ -0,0 +1,66 @@
+/*
+ * Voipac PXA270 OneNAND SPL
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * 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>
+#include <config.h>
+#include <asm/io.h>
+#include <onenand_uboot.h>
+
+extern void pxa_dram_init(void);
+
+void board_init_f(unsigned long unused)
+{
+	extern uint32_t _end;
+	uint32_t tmp;
+
+	asm volatile("mov %0, pc" : "=r"(tmp));
+	tmp >>= 24;
+
+	/* The code runs from OneNAND RAM, copy SPL to SRAM and execute it. */
+	if (tmp == 0) {
+		tmp = (uint32_t)&_end - CONFIG_SPL_TEXT_BASE;
+		onenand_spl_load_image(0, tmp, (void *)CONFIG_SPL_TEXT_BASE);
+		asm volatile("mov pc, %0" : : "r"(CONFIG_SPL_TEXT_BASE));
+	}
+
+	/* Hereby, the code runs from (S)RAM, copy U-Boot and execute it. */
+	arch_cpu_init();
+	pxa_dram_init();
+	onenand_spl_load_image(CONFIG_SPL_ONENAND_LOAD_ADDR,
+				CONFIG_SPL_ONENAND_LOAD_SIZE,
+				(void *)CONFIG_SYS_TEXT_BASE);
+	asm volatile("mov pc, %0" : : "r"(CONFIG_SYS_TEXT_BASE));
+
+	for (;;)
+		;
+}
+
+void __attribute__((noreturn)) hang(void)
+{
+	for (;;)
+		;
+}
+
+void icache_disable(void) {}
+void dcache_disable(void) {}
diff --git a/board/vpac270/u-boot-spl.lds b/board/vpac270/u-boot-spl.lds
new file mode 100644
index 0000000..1958c2f
--- /dev/null
+++ b/board/vpac270/u-boot-spl.lds
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * January 2004 - Changed to support H4 device
+ * Copyright (c) 2004-2008 Texas Instruments
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@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
+{
+	. = CONFIG_SPL_TEXT_BASE;
+	.text.0	:
+	{
+		arch/arm/cpu/pxa/start.o		(.text*)
+		board/vpac270/libvpac270.o		(.text*)
+		drivers/mtd/onenand/libonenand.o	(.text*)
+	}
+
+
+	/* Start of the rest of the SPL */
+	. = CONFIG_SPL_TEXT_BASE + 0x800;
+
+	.text.1	:
+	{
+		*(.text*)
+	}
+
+	. = ALIGN(4);
+	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+	. = ALIGN(4);
+	.data : {
+		*(.data)
+	}
+
+	. = ALIGN(4);
+
+	.rel.dyn : {
+		__rel_dyn_start = .;
+		*(.rel*)
+		__rel_dyn_end = .;
+	}
+
+	.dynsym : {
+		__dynsym_start = .;
+		*(.dynsym)
+	}
+
+	. = ALIGN(0x800);
+
+	_end = .;
+
+	.bss __rel_dyn_start (OVERLAY) : {
+		__bss_start = .;
+		*(.bss)
+		 . = ALIGN(4);
+		__bss_end__ = .;
+	}
+
+	/DISCARD/ : { *(.bss*) }
+	/DISCARD/ : { *(.dynstr*) }
+	/DISCARD/ : { *(.dynsym*) }
+	/DISCARD/ : { *(.dynamic*) }
+	/DISCARD/ : { *(.hash*) }
+	/DISCARD/ : { *(.plt*) }
+	/DISCARD/ : { *(.interp*) }
+	/DISCARD/ : { *(.gnu*) }
+}
diff --git a/board/vpac270/vpac270.c b/board/vpac270/vpac270.c
index cf8e7b6..d90a859 100644
--- a/board/vpac270/vpac270.c
+++ b/board/vpac270/vpac270.c
@@ -57,7 +57,9 @@ struct serial_device *default_serial_console(void)
 extern void pxa_dram_init(void);
 int dram_init(void)
 {
+#ifndef	CONFIG_ONENAND
 	pxa_dram_init();
+#endif
 	gd->ram_size = PHYS_SDRAM_1_SIZE;
 	return 0;
 }
diff --git a/include/configs/vpac270.h b/include/configs/vpac270.h
index dd68c66..8accebf 100644
--- a/include/configs/vpac270.h
+++ b/include/configs/vpac270.h
@@ -27,7 +27,17 @@
  */
 #define	CONFIG_PXA27X		1	/* Marvell PXA270 CPU */
 #define	CONFIG_VPAC270		1	/* Voipac PXA270 board */
-#define	CONFIG_SYS_TEXT_BASE	0x0
+#define	CONFIG_SYS_TEXT_BASE	0xa0000000
+
+#ifdef	CONFIG_ONENAND
+#define	CONFIG_SPL
+#define	CONFIG_SPL_ONENAND_SUPPORT
+#define	CONFIG_SPL_ONENAND_LOAD_ADDR	0x2000
+#define	CONFIG_SPL_ONENAND_LOAD_SIZE	\
+	(512 * 1024 - CONFIG_SPL_ONENAND_LOAD_ADDR)
+#define	CONFIG_SPL_TEXT_BASE	0x5c000000
+#define	CONFIG_SPL_LDSCRIPT	"board/vpac270/u-boot-spl.lds"
+#endif
 
 /*
  * Environment settings
@@ -46,12 +56,19 @@
 		"bootm 0xa4000000; "					\
 	"fi; "								\
 	"bootm 0x60000;"
+
+#define	CONFIG_EXTRA_ENV_SETTINGS					\
+	"update_onenand="						\
+		"onenand erase 0x0 0x80000 ; "				\
+		"onenand write 0xa0000000 0x0 0x80000"
+
 #define	CONFIG_BOOTARGS			"console=tty0 console=ttyS0,115200"
 #define	CONFIG_TIMESTAMP
 #define	CONFIG_BOOTDELAY		2	/* Autoboot delay */
 #define	CONFIG_CMDLINE_TAG
 #define	CONFIG_SETUP_MEMORY_TAGS
 #define	CONFIG_LZMA			/* LZMA compression support */
+#define	CONFIG_OF_LIBFDT
 
 /*
  * Serial Console Configuration
@@ -180,16 +197,14 @@
 #define	CONFIG_SYS_MEMTEST_END		0xa0800000	/* 4 ... 8 MB in DRAM */
 
 #define	CONFIG_SYS_LOAD_ADDR		PHYS_SDRAM_1
-#define	CONFIG_SYS_IPL_LOAD_ADDR	(0x5c000000)
 #define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
-#define	CONFIG_SYS_INIT_SP_ADDR		\
-	(PHYS_SDRAM_1 + GENERATED_GBL_DATA_SIZE + 2048)
+#define	CONFIG_SYS_INIT_SP_ADDR		0x5c010000
 
 /*
  * NOR FLASH
  */
 #define	CONFIG_SYS_MONITOR_BASE		0x0
-#define	CONFIG_SYS_MONITOR_LEN		0x40000
+#define	CONFIG_SYS_MONITOR_LEN		0x80000
 #define	CONFIG_ENV_ADDR			\
 			(CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN)
 #define	CONFIG_ENV_SIZE			0x4000
-- 
1.7.6.3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 3/4 V2] OneNAND: Add simple OneNAND SPL
  2011-11-03  0:15       ` Marek Vasut
  2011-11-03  0:36         ` Kyungmin Park
@ 2011-11-03 16:19         ` Scott Wood
  2011-11-03 16:56           ` Marek Vasut
  1 sibling, 1 reply; 38+ messages in thread
From: Scott Wood @ 2011-11-03 16:19 UTC (permalink / raw)
  To: u-boot

On 11/02/2011 07:15 PM, Marek Vasut wrote:
>> On 11/01/2011 05:54 PM, Marek Vasut wrote:
>>> +static void spl_onenand_get_geometry(struct spl_onenand_data *data)
>>> +{
> [...]
> 
>>> +	/* The page can be either 2k or 4k, avoid using DIV_ROUND_UP. */
>>> +	if (data.pagesize == 2048) {
>>> +		total_pages = len / 2048;
>>> +		page = offset / 2048;
>>> +		total_pages += !!(len & 2047);
>>> +	} else if (data.pagesize == 4096) {
>>> +		total_pages = len / 4096;
>>> +		page = offset / 4096;
>>> +		total_pages += !!(len & 4095);
>>> +	}
>>
>> What's wrong with DIV_ROUND_UP?  It should produce smaller code than
>> what you've done here...
> 
> It pulls in aeabi_*div* functions, which won't fit into block 0 of Onenand.

It shouldn't do that if the divisor is a constant power of 2.  The
compiler will turn it into a shift, just like with the other divides in
the above code fragment.

You can't use DIV_ROUND_UP directly on data.pagesize, but you can use it
in each branch of the if statement instead of that awkward and slightly
more expensive !!(len & 4095) construct.

-Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 3/4 V2] OneNAND: Add simple OneNAND SPL
  2011-11-03 16:19         ` Scott Wood
@ 2011-11-03 16:56           ` Marek Vasut
  2011-11-03 17:06             ` Scott Wood
  0 siblings, 1 reply; 38+ messages in thread
From: Marek Vasut @ 2011-11-03 16:56 UTC (permalink / raw)
  To: u-boot

> On 11/02/2011 07:15 PM, Marek Vasut wrote:
> >> On 11/01/2011 05:54 PM, Marek Vasut wrote:
> >>> +static void spl_onenand_get_geometry(struct spl_onenand_data *data)
> >>> +{
> > 
> > [...]
> > 
> >>> +	/* The page can be either 2k or 4k, avoid using DIV_ROUND_UP. */
> >>> +	if (data.pagesize == 2048) {
> >>> +		total_pages = len / 2048;
> >>> +		page = offset / 2048;
> >>> +		total_pages += !!(len & 2047);
> >>> +	} else if (data.pagesize == 4096) {
> >>> +		total_pages = len / 4096;
> >>> +		page = offset / 4096;
> >>> +		total_pages += !!(len & 4095);
> >>> +	}
> >> 
> >> What's wrong with DIV_ROUND_UP?  It should produce smaller code than
> >> what you've done here...
> > 
> > It pulls in aeabi_*div* functions, which won't fit into block 0 of
> > Onenand.
> 
> It shouldn't do that if the divisor is a constant power of 2.  The
> compiler will turn it into a shift, just like with the other divides in
> the above code fragment.
> 
> You can't use DIV_ROUND_UP directly on data.pagesize, but you can use it
> in each branch of the if statement instead of that awkward and slightly
> more expensive !!(len & 4095) construct.

Expensive in what way? Either way, I don't think this matters that much.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 3/4 V2] OneNAND: Add simple OneNAND SPL
  2011-11-03 16:56           ` Marek Vasut
@ 2011-11-03 17:06             ` Scott Wood
  2011-11-03 17:25               ` Marek Vasut
  0 siblings, 1 reply; 38+ messages in thread
From: Scott Wood @ 2011-11-03 17:06 UTC (permalink / raw)
  To: u-boot

On 11/03/2011 11:56 AM, Marek Vasut wrote:
>> On 11/02/2011 07:15 PM, Marek Vasut wrote:
>>>> On 11/01/2011 05:54 PM, Marek Vasut wrote:
>>>>> +static void spl_onenand_get_geometry(struct spl_onenand_data *data)
>>>>> +{
>>>
>>> [...]
>>>
>>>>> +	/* The page can be either 2k or 4k, avoid using DIV_ROUND_UP. */
>>>>> +	if (data.pagesize == 2048) {
>>>>> +		total_pages = len / 2048;
>>>>> +		page = offset / 2048;
>>>>> +		total_pages += !!(len & 2047);
>>>>> +	} else if (data.pagesize == 4096) {
>>>>> +		total_pages = len / 4096;
>>>>> +		page = offset / 4096;
>>>>> +		total_pages += !!(len & 4095);
>>>>> +	}
>>>>
>>>> What's wrong with DIV_ROUND_UP?  It should produce smaller code than
>>>> what you've done here...
>>>
>>> It pulls in aeabi_*div* functions, which won't fit into block 0 of
>>> Onenand.
>>
>> It shouldn't do that if the divisor is a constant power of 2.  The
>> compiler will turn it into a shift, just like with the other divides in
>> the above code fragment.
>>
>> You can't use DIV_ROUND_UP directly on data.pagesize, but you can use it
>> in each branch of the if statement instead of that awkward and slightly
>> more expensive !!(len & 4095) construct.
> 
> Expensive in what way?

Compare the resulting asm code.  You're replacing this:

	a = (b + 4095) >> 12;

with this:

	a = b >> 12;
	if (b & 4095)
		a++;

>  Either way, I don't think this matters that much.

This is code that has to fit in 1K -- why waste instructions by writing
code in a way that is *less* readable?

-Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 3/4 V2] OneNAND: Add simple OneNAND SPL
  2011-11-03 17:06             ` Scott Wood
@ 2011-11-03 17:25               ` Marek Vasut
  0 siblings, 0 replies; 38+ messages in thread
From: Marek Vasut @ 2011-11-03 17:25 UTC (permalink / raw)
  To: u-boot

> On 11/03/2011 11:56 AM, Marek Vasut wrote:
> >> On 11/02/2011 07:15 PM, Marek Vasut wrote:
> >>>> On 11/01/2011 05:54 PM, Marek Vasut wrote:
> >>>>> +static void spl_onenand_get_geometry(struct spl_onenand_data *data)
> >>>>> +{
> >>> 
> >>> [...]
> >>> 
> >>>>> +	/* The page can be either 2k or 4k, avoid using DIV_ROUND_UP. */
> >>>>> +	if (data.pagesize == 2048) {
> >>>>> +		total_pages = len / 2048;
> >>>>> +		page = offset / 2048;
> >>>>> +		total_pages += !!(len & 2047);
> >>>>> +	} else if (data.pagesize == 4096) {
> >>>>> +		total_pages = len / 4096;
> >>>>> +		page = offset / 4096;
> >>>>> +		total_pages += !!(len & 4095);
> >>>>> +	}
> >>>> 
> >>>> What's wrong with DIV_ROUND_UP?  It should produce smaller code than
> >>>> what you've done here...
> >>> 
> >>> It pulls in aeabi_*div* functions, which won't fit into block 0 of
> >>> Onenand.
> >> 
> >> It shouldn't do that if the divisor is a constant power of 2.  The
> >> compiler will turn it into a shift, just like with the other divides in
> >> the above code fragment.
> >> 
> >> You can't use DIV_ROUND_UP directly on data.pagesize, but you can use it
> >> in each branch of the if statement instead of that awkward and slightly
> >> more expensive !!(len & 4095) construct.
> > 
> > Expensive in what way?
> 
> Compare the resulting asm code.  You're replacing this:
> 
> 	a = (b + 4095) >> 12;
> 
> with this:
> 
> 	a = b >> 12;
> 	if (b & 4095)
> 		a++;
> 
> >  Either way, I don't think this matters that much.
> 
> This is code that has to fit in 1K -- why waste instructions by writing
> code in a way that is *less* readable?

The size is the same (tested). I'll submit a patch with DIV_ROUND_UP, whatever.

> 
> -Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4 V3] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-11-03  1:56     ` [U-Boot] [PATCH 4/4 V3] " Marek Vasut
@ 2011-11-03 18:09       ` Scott Wood
  2011-11-03 21:52         ` Marek Vasut
  0 siblings, 1 reply; 38+ messages in thread
From: Scott Wood @ 2011-11-03 18:09 UTC (permalink / raw)
  To: u-boot

On 11/02/2011 08:56 PM, Marek Vasut wrote:
> +	onenand_spl_load_image(CONFIG_SPL_ONENAND_LOAD_ADDR,
> +				CONFIG_SPL_ONENAND_LOAD_SIZE,
> +				(void *)CONFIG_SYS_TEXT_BASE);

If we make it "nand_spl_load_image", and make the #defines conform, we
can have the same code call the function for nand and onenand.  I don't
see any reason why onenand is a completely different subsystem in
general, rather than just another NAND driver.  The NAND subsystem's
driver interface is lower level than it should be, but that affects
other NAND controllers as well (such as fsl_elbc).

Switching to the generic nand_boot() in
http://patchwork.ozlabs.org/patch/123219/ would get you the ability to
load the environment during the SPL.

-Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4 V3] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-11-03 18:09       ` Scott Wood
@ 2011-11-03 21:52         ` Marek Vasut
  2011-11-03 22:20           ` Scott Wood
  0 siblings, 1 reply; 38+ messages in thread
From: Marek Vasut @ 2011-11-03 21:52 UTC (permalink / raw)
  To: u-boot

> On 11/02/2011 08:56 PM, Marek Vasut wrote:
> > +	onenand_spl_load_image(CONFIG_SPL_ONENAND_LOAD_ADDR,
> > +				CONFIG_SPL_ONENAND_LOAD_SIZE,
> > +				(void *)CONFIG_SYS_TEXT_BASE);
> 
> If we make it "nand_spl_load_image", and make the #defines conform, we
> can have the same code call the function for nand and onenand.  I don't
> see any reason why onenand is a completely different subsystem in
> general, rather than just another NAND driver.  The NAND subsystem's
> driver interface is lower level than it should be, but that affects
> other NAND controllers as well (such as fsl_elbc).
> 
> Switching to the generic nand_boot() in
> http://patchwork.ozlabs.org/patch/123219/ would get you the ability to
> load the environment during the SPL.
> 
> -Scott

I don't think I understand. Why do you want to mix onenand and nand ? Also, will 
your approach still allow me to squeeze the important code into the first 1kb 
for the initial copying of SPL?

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 3/4 V4] OneNAND: Add simple OneNAND SPL
  2011-11-03  1:55     ` [U-Boot] [PATCH 3/4 V3] " Marek Vasut
@ 2011-11-03 21:59       ` Marek Vasut
  0 siblings, 0 replies; 38+ messages in thread
From: Marek Vasut @ 2011-11-03 21:59 UTC (permalink / raw)
  To: u-boot

This introduces small OneNAND loader, fitting into 1kB of space (smallest
possible OneNAND RAM size). Some devices equipped with such crappy chips will
use this.

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Scott Wood <scottwood@freescale.com>
---
 drivers/mtd/onenand/Makefile      |    4 +
 drivers/mtd/onenand/onenand_spl.c |  146 +++++++++++++++++++++++++++++++++++++
 include/onenand_uboot.h           |    3 +
 spl/Makefile                      |    1 +
 4 files changed, 154 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/onenand/onenand_spl.c

V2: Introduce spl_onenand_load_image() to load data from OneNAND in SPL
V3: Cleanup, align with nand_spl. Skip whole blocks.
V4: Use DIV_ROUND_UP.

diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
index b984bd4..b090d40 100644
--- a/drivers/mtd/onenand/Makefile
+++ b/drivers/mtd/onenand/Makefile
@@ -25,8 +25,12 @@ include $(TOPDIR)/config.mk
 
 LIB	:= $(obj)libonenand.o
 
+ifndef	CONFIG_SPL_BUILD
 COBJS-$(CONFIG_CMD_ONENAND)	:= onenand_uboot.o onenand_base.o onenand_bbt.o
 COBJS-$(CONFIG_SAMSUNG_ONENAND)	+= samsung.o
+else
+COBJS-y				:= onenand_spl.o
+endif
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/mtd/onenand/onenand_spl.c b/drivers/mtd/onenand/onenand_spl.c
new file mode 100644
index 0000000..50eaa71
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_spl.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on code:
+ *	Copyright (C) 2005-2009 Samsung Electronics
+ *	Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * 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>
+#include <asm/io.h>
+#include <linux/mtd/onenand_regs.h>
+#include <onenand_uboot.h>
+
+/*
+ * Device geometry:
+ * - 2048b page, 128k erase block.
+ * - 4096b page, 256k erase block.
+ */
+enum onenand_spl_pagesize {
+	PAGE_2K = 2048,
+	PAGE_4K = 4096,
+};
+
+#define ONENAND_PAGES_PER_BLOCK			64
+#define onenand_block_address(block)		(block)
+#define onenand_sector_address(page)		(page << 2)
+#define onenand_buffer_address()		((1 << 3) << 8)
+#define onenand_bufferram_address(block)	(0)
+
+static inline uint16_t onenand_readw(uint32_t addr)
+{
+	return readw(CONFIG_SYS_ONENAND_BASE + addr);
+}
+
+static inline void onenand_writew(uint16_t value, uint32_t addr)
+{
+	writew(value, CONFIG_SYS_ONENAND_BASE + addr);
+}
+
+static enum onenand_spl_pagesize onenand_spl_get_geometry(void)
+{
+	uint32_t dev_id, density;
+
+	if (!onenand_readw(ONENAND_REG_TECHNOLOGY)) {
+		dev_id = onenand_readw(ONENAND_REG_DEVICE_ID);
+		density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
+		density &= ONENAND_DEVICE_DENSITY_MASK;
+
+		if (density < ONENAND_DEVICE_DENSITY_4Gb)
+			return PAGE_2K;
+
+		if (dev_id & ONENAND_DEVICE_IS_DDP)
+			return PAGE_2K;
+	}
+
+	return PAGE_4K;
+}
+
+static int onenand_spl_read_page(uint32_t block, uint32_t page, uint32_t *buf,
+					enum onenand_spl_pagesize pagesize)
+{
+	const uint32_t addr = CONFIG_SYS_ONENAND_BASE + ONENAND_DATARAM;
+	uint32_t offset;
+
+	onenand_writew(onenand_block_address(block),
+			ONENAND_REG_START_ADDRESS1);
+
+	onenand_writew(onenand_bufferram_address(block),
+			ONENAND_REG_START_ADDRESS2);
+
+	onenand_writew(onenand_sector_address(page),
+			ONENAND_REG_START_ADDRESS8);
+
+	onenand_writew(onenand_buffer_address(),
+			ONENAND_REG_START_BUFFER);
+
+	onenand_writew(ONENAND_INT_CLEAR, ONENAND_REG_INTERRUPT);
+
+	onenand_writew(ONENAND_CMD_READ, ONENAND_REG_COMMAND);
+
+	while (!(onenand_readw(ONENAND_REG_INTERRUPT) & ONENAND_INT_READ))
+		continue;
+
+	/* Check for invalid block mark */
+	if (page < 2 && (onenand_readw(ONENAND_SPARERAM) != 0xffff))
+		return 1;
+
+	for (offset = 0; offset < pagesize; offset += 4)
+		buf[offset / 4] = readl(addr + offset);
+
+	return 0;
+}
+
+void onenand_spl_load_image(uint32_t offs, uint32_t size, void *dst)
+{
+	uint32_t *addr = (uint32_t *)dst;
+	uint32_t total_pages;
+	uint32_t block;
+	uint32_t page, rpage;
+	enum onenand_spl_pagesize pagesize;
+	int ret;
+
+	pagesize = onenand_spl_get_geometry();
+
+	/*
+	 * The page can be either 2k or 4k, avoid using DIV_ROUND_UP to avoid
+	 * pulling further unwanted functions into the SPL.
+	 */
+	if (pagesize == 2048) {
+		total_pages = DIV_ROUND_UP(size, 2048);
+		page = offs / 2048;
+	} else {
+		total_pages = DIV_ROUND_UP(size, 4096);
+		page = offs / 4096;
+	}
+
+	for (; page <= total_pages; page++) {
+		block = page / ONENAND_PAGES_PER_BLOCK;
+		rpage = page & (ONENAND_PAGES_PER_BLOCK - 1);
+		ret = onenand_spl_read_page(block, rpage, addr, pagesize);
+		if (ret) {
+			total_pages += ONENAND_PAGES_PER_BLOCK;
+			page += ONENAND_PAGES_PER_BLOCK - 1;
+		} else {
+			addr += pagesize / 4;
+		}
+	}
+}
diff --git a/include/onenand_uboot.h b/include/onenand_uboot.h
index 92279d5..f321d8a 100644
--- a/include/onenand_uboot.h
+++ b/include/onenand_uboot.h
@@ -52,4 +52,7 @@ extern int flexonenand_set_boundary(struct mtd_info *mtd, int die,
 extern void s3c64xx_onenand_init(struct mtd_info *);
 extern void s3c64xx_set_width_regs(struct onenand_chip *);
 
+/* SPL */
+void onenand_spl_load_image(uint32_t offs, uint32_t size, void *dst);
+
 #endif /* __UBOOT_ONENAND_H */
diff --git a/spl/Makefile b/spl/Makefile
index d4d754d..b4001bf 100644
--- a/spl/Makefile
+++ b/spl/Makefile
@@ -54,6 +54,7 @@ LIBS-$(CONFIG_SPL_FAT_SUPPORT) += fs/fat/libfat.o
 LIBS-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/libgeneric.o
 LIBS-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/libpower.o
 LIBS-$(CONFIG_SPL_NAND_SUPPORT) += drivers/mtd/nand/libnand.o
+LIBS-$(CONFIG_SPL_ONENAND_SUPPORT) += drivers/mtd/onenand/libonenand.o
 LIBS-$(CONFIG_SPL_DMA_SUPPORT) += drivers/dma/libdma.o
 
 ifeq ($(SOC),omap3)
-- 
1.7.6.3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4 V3] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-11-03 21:52         ` Marek Vasut
@ 2011-11-03 22:20           ` Scott Wood
  2011-11-04  0:55             ` Marek Vasut
  0 siblings, 1 reply; 38+ messages in thread
From: Scott Wood @ 2011-11-03 22:20 UTC (permalink / raw)
  To: u-boot

On 11/03/2011 04:52 PM, Marek Vasut wrote:
>> On 11/02/2011 08:56 PM, Marek Vasut wrote:
>>> +	onenand_spl_load_image(CONFIG_SPL_ONENAND_LOAD_ADDR,
>>> +				CONFIG_SPL_ONENAND_LOAD_SIZE,
>>> +				(void *)CONFIG_SYS_TEXT_BASE);
>>
>> If we make it "nand_spl_load_image", and make the #defines conform, we
>> can have the same code call the function for nand and onenand.  I don't
>> see any reason why onenand is a completely different subsystem in
>> general, rather than just another NAND driver.  The NAND subsystem's
>> driver interface is lower level than it should be, but that affects
>> other NAND controllers as well (such as fsl_elbc).
>>
>> Switching to the generic nand_boot() in
>> http://patchwork.ozlabs.org/patch/123219/ would get you the ability to
>> load the environment during the SPL.
>>
>> -Scott
> 
> I don't think I understand. Why do you want to mix onenand and nand ?

Why do we want to separate them?  What is the fundamental difference
between OneNAND, and a high-level NAND controller such as fsl_elbc?
Maybe there would be some differences on init if we can't produce
"normal" ID data, but that doesn't justify duplicating the whole subsystem.

Why should the code that just wants to use an API to move data around
need to care which it is?  Why should there be behavioral differences
that aren't rooted in the actual hardware?  Another approach might be to
use MTD as the common interface, but factor out common code into
libraries that drivers can use, and avoid the main nand_base.c code even
for things like fsl_elbc.

This is not a new complaint -- I've asked for this before but nobody's
put the time into sorting out the mess (and I have neither time nor
hardware nor documentation).  The SPL load_image function is a simple
enough interface to start with, though. :-)

In fact, it should probably just be spl_load_image() with whatever boot
source has been configured into this SPL build.

> Also, will your approach still allow me to squeeze the important code into the first 1kb 
> for the initial copying of SPL?

If you can't fit the common load sequence in, then of course don't use
it, but there's no need for the function name to be different.

-Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4 V3] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-11-03 22:20           ` Scott Wood
@ 2011-11-04  0:55             ` Marek Vasut
  2011-11-04 16:37               ` Scott Wood
  0 siblings, 1 reply; 38+ messages in thread
From: Marek Vasut @ 2011-11-04  0:55 UTC (permalink / raw)
  To: u-boot

> On 11/03/2011 04:52 PM, Marek Vasut wrote:
> >> On 11/02/2011 08:56 PM, Marek Vasut wrote:
> >>> +	onenand_spl_load_image(CONFIG_SPL_ONENAND_LOAD_ADDR,
> >>> +				CONFIG_SPL_ONENAND_LOAD_SIZE,
> >>> +				(void *)CONFIG_SYS_TEXT_BASE);
> >> 
> >> If we make it "nand_spl_load_image", and make the #defines conform, we
> >> can have the same code call the function for nand and onenand.  I don't
> >> see any reason why onenand is a completely different subsystem in
> >> general, rather than just another NAND driver.  The NAND subsystem's
> >> driver interface is lower level than it should be, but that affects
> >> other NAND controllers as well (such as fsl_elbc).
> >> 
> >> Switching to the generic nand_boot() in
> >> http://patchwork.ozlabs.org/patch/123219/ would get you the ability to
> >> load the environment during the SPL.
> >> 
> >> -Scott
> > 
> > I don't think I understand. Why do you want to mix onenand and nand ?
> 
> Why do we want to separate them?  What is the fundamental difference
> between OneNAND, and a high-level NAND controller such as fsl_elbc?

Honestly, I'm not the author of the subsystem, but please check the 
documentation. The way we retrieve data from onenand is different to NAND.

> Maybe there would be some differences on init if we can't produce
> "normal" ID data, but that doesn't justify duplicating the whole subsystem.

Where do you see such duplication? cmd_onenand ?
> 
> Why should the code that just wants to use an API to move data around
> need to care which it is?  Why should there be behavioral differences
> that aren't rooted in the actual hardware?  Another approach might be to
> use MTD as the common interface, but factor out common code into
> libraries that drivers can use, and avoid the main nand_base.c code even
> for things like fsl_elbc.

I think you're mistaken here. OneNAND != NAND.
> 
> This is not a new complaint -- I've asked for this before but nobody's
> put the time into sorting out the mess (and I have neither time nor
> hardware nor documentation).  The SPL load_image function is a simple
> enough interface to start with, though. :-)

Well, it seems what you are proposing is way beyond the scope of this patchset.
> 
> In fact, it should probably just be spl_load_image() with whatever boot
> source has been configured into this SPL build.

What if you have two boot sources?

> 
> > Also, will your approach still allow me to squeeze the important code
> > into the first 1kb for the initial copying of SPL?
> 
> If you can't fit the common load sequence in, then of course don't use
> it, but there's no need for the function name to be different.
> 
> -Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4 V3] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-11-04  0:55             ` Marek Vasut
@ 2011-11-04 16:37               ` Scott Wood
  2011-11-04 20:07                 ` Marek Vasut
  0 siblings, 1 reply; 38+ messages in thread
From: Scott Wood @ 2011-11-04 16:37 UTC (permalink / raw)
  To: u-boot

On 11/03/2011 07:55 PM, Marek Vasut wrote:
>> On 11/03/2011 04:52 PM, Marek Vasut wrote:
>> Why do we want to separate them?  What is the fundamental difference
>> between OneNAND, and a high-level NAND controller such as fsl_elbc?
> 
> Honestly, I'm not the author of the subsystem, but please check the 
> documentation. The way we retrieve data from onenand is different to NAND.

What documentation?  How is it different?  There are substantial
differences in how we "retrieve data" between drivers that use the NAND
subsystem.  Surely you've seen that in the mxs_nand driver. :-)

>> Maybe there would be some differences on init if we can't produce
>> "normal" ID data, but that doesn't justify duplicating the whole subsystem.
> 
> Where do you see such duplication? cmd_onenand ?

cmd_onenand and env_onenand are the most irritating, since they're at a
layer that really shouldn't care about the differences -- we should
probably have a plain "mtd" command instead, for most of the functionality.

There's also onenand_bbt.c -- what are the hardware-based differences in
how the bad block table is managed?

nand_base.c/onenand_base.c are less clear.  Obviously much of what is in
onenand_base.c would be in the controller driver if it used the NAND
subsystem.  But it looks like some of it is duplication.

>> Why should the code that just wants to use an API to move data around
>> need to care which it is?  Why should there be behavioral differences
>> that aren't rooted in the actual hardware?  Another approach might be to
>> use MTD as the common interface, but factor out common code into
>> libraries that drivers can use, and avoid the main nand_base.c code even
>> for things like fsl_elbc.
> 
> I think you're mistaken here. OneNAND != NAND.

Well, last I tried I couldn't find any public documentation, so all I
have to go on is the code, some marketing-type info, and asking
questions of people that appear to know more about OneNAND than I do. :-)

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4 V3] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-11-04 16:37               ` Scott Wood
@ 2011-11-04 20:07                 ` Marek Vasut
  2011-11-04 20:13                   ` Scott Wood
  0 siblings, 1 reply; 38+ messages in thread
From: Marek Vasut @ 2011-11-04 20:07 UTC (permalink / raw)
  To: u-boot

> On 11/03/2011 07:55 PM, Marek Vasut wrote:
> >> On 11/03/2011 04:52 PM, Marek Vasut wrote:
> >> Why do we want to separate them?  What is the fundamental difference
> >> between OneNAND, and a high-level NAND controller such as fsl_elbc?
> > 
> > Honestly, I'm not the author of the subsystem, but please check the
> > documentation. The way we retrieve data from onenand is different to
> > NAND.
> 
> What documentation?  How is it different?  There are substantial
> differences in how we "retrieve data" between drivers that use the NAND
> subsystem.  Surely you've seen that in the mxs_nand driver. :-)
> 
> >> Maybe there would be some differences on init if we can't produce
> >> "normal" ID data, but that doesn't justify duplicating the whole
> >> subsystem.
> > 
> > Where do you see such duplication? cmd_onenand ?
> 
> cmd_onenand and env_onenand are the most irritating, since they're at a
> layer that really shouldn't care about the differences -- we should
> probably have a plain "mtd" command instead, for most of the functionality.
> 
> There's also onenand_bbt.c -- what are the hardware-based differences in
> how the bad block table is managed?
> 
> nand_base.c/onenand_base.c are less clear.  Obviously much of what is in
> onenand_base.c would be in the controller driver if it used the NAND
> subsystem.  But it looks like some of it is duplication.
> 
> >> Why should the code that just wants to use an API to move data around
> >> need to care which it is?  Why should there be behavioral differences
> >> that aren't rooted in the actual hardware?  Another approach might be to
> >> use MTD as the common interface, but factor out common code into
> >> libraries that drivers can use, and avoid the main nand_base.c code even
> >> for things like fsl_elbc.
> > 
> > I think you're mistaken here. OneNAND != NAND.
> 
> Well, last I tried I couldn't find any public documentation, so all I
> have to go on is the code, some marketing-type info, and asking
> questions of people that appear to know more about OneNAND than I do. :-)
> 
> From what I can see, it looks like NAND with an integrated controller
> that exposes an unusual command set, but still for the most part
> provides the same operations.  Several of our existing NAND-subsystem
> drivers have to fake the command set for the generic layer as well.
> Initialization/identification might be a problem area that current
> drivers don't have to deal with, though.  Actually integrating OneNAND
> with NAND would likely involve an already-needed restructuring of the
> subsystem.
> 
> If the answer really is that it makes sense to consider OneNAND to be a
> totally different thing from NAND, then it's outside my jurisdiction as
> NAND custodian -- which is fine with me.  Frankly, even if it does make
> sense to merge them, I'd rather not be custodian of the OneNAND stuff
> unless someone is actually willing to do the merge.  I don't have access
> to hardware or documentation, and it's an entirely separate codebase.
> People just started sending me the patches a few years back.
> 
> >> This is not a new complaint -- I've asked for this before but nobody's
> >> put the time into sorting out the mess (and I have neither time nor
> >> hardware nor documentation).  The SPL load_image function is a simple
> >> enough interface to start with, though. :-)
> > 
> > Well, it seems what you are proposing is way beyond the scope of this
> > patchset.
> > 
> >> In fact, it should probably just be spl_load_image() with whatever boot
> >> source has been configured into this SPL build.
> > 
> > What if you have two boot sources?
> 
> Traditionally SPL has been small and purpose-built to do exactly one
> thing -- so we decide at compile-time things that we might otherwise
> decide at runtime.
> 
> If there's a requirement for multiple boot sources decided at runtime,
> then we'll obviously need a runtime mechanism. -- but it seems a bit
> hackish to why does it matter whether it's two different types of
> device, or two of the same type of device (possibly with different
> controller types)?  If the answer is that, for example, NAND versus USB
> versus MMC is a likely use case, but two different NANDs is not likely,
> is NAND versus OneNAND any more likely?
> 
> Maybe spl_load_image should be a function pointer that board code sets,
> with each implementation being distinctly named (in which case
> nand_spl_load_image would become nand_spl_simple_load_image, unless we
> move it to nand_spl_load.c and make nand_read_page a function pointer).
>  If needed to save a few bytes, we could use #defines to eliminate the
> function pointers in a single-target SPL build.
> 
> For now, until we decide to do something SPL-wide, call it what you want.
> 

Well basically from what I see, you'd like me to do the NAND/OneNAND merge. As I 
already said, that's way out of the scope of this patchset so I'm not doing 
that. Either way, are you OK with current state of the patch?

M

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4 V3] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-11-04 20:07                 ` Marek Vasut
@ 2011-11-04 20:13                   ` Scott Wood
  2011-11-04 20:31                     ` Marek Vasut
  2011-11-05 22:40                     ` Marek Vasut
  0 siblings, 2 replies; 38+ messages in thread
From: Scott Wood @ 2011-11-04 20:13 UTC (permalink / raw)
  To: u-boot

On 11/04/2011 03:07 PM, Marek Vasut wrote:
>> For now, until we decide to do something SPL-wide, call it what you want.
>>
> 
> Well basically from what I see, you'd like me to do the NAND/OneNAND merge. As I 
> already said, that's way out of the scope of this patchset so I'm not doing 
> that.

Oh, I didn't mean to imply that was within the scope of this patch.  I
was just describing the background behind why I'm frustrated with the
OneNAND situation, and this looked like an extension of the "onenand is
a totally different thing" model, in an independent context.

> Either way, are you OK with current state of the patch?

I won't block it.

-Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4 V3] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-11-04 20:13                   ` Scott Wood
@ 2011-11-04 20:31                     ` Marek Vasut
  2011-11-05 22:40                     ` Marek Vasut
  1 sibling, 0 replies; 38+ messages in thread
From: Marek Vasut @ 2011-11-04 20:31 UTC (permalink / raw)
  To: u-boot

> On 11/04/2011 03:07 PM, Marek Vasut wrote:
> >> For now, until we decide to do something SPL-wide, call it what you
> >> want.
> > 
> > Well basically from what I see, you'd like me to do the NAND/OneNAND
> > merge. As I already said, that's way out of the scope of this patchset
> > so I'm not doing that.
> 
> Oh, I didn't mean to imply that was within the scope of this patch.  I
> was just describing the background behind why I'm frustrated with the
> OneNAND situation, and this looked like an extension of the "onenand is
> a totally different thing" model, in an independent context.

Well I suppose this is rooted in Linux. It's different subsys there too.
> 
> > Either way, are you OK with current state of the patch?
> 
> I won't block it.

That's what I meant.

> 
> -Scott

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [U-Boot] [PATCH 4/4 V3] PXA: Adapt Voipac PXA270 to OneNAND SPL
  2011-11-04 20:13                   ` Scott Wood
  2011-11-04 20:31                     ` Marek Vasut
@ 2011-11-05 22:40                     ` Marek Vasut
  1 sibling, 0 replies; 38+ messages in thread
From: Marek Vasut @ 2011-11-05 22:40 UTC (permalink / raw)
  To: u-boot

> On 11/04/2011 03:07 PM, Marek Vasut wrote:
> >> For now, until we decide to do something SPL-wide, call it what you
> >> want.
> > 
> > Well basically from what I see, you'd like me to do the NAND/OneNAND
> > merge. As I already said, that's way out of the scope of this patchset
> > so I'm not doing that.
> 
> Oh, I didn't mean to imply that was within the scope of this patch.  I
> was just describing the background behind why I'm frustrated with the
> OneNAND situation, and this looked like an extension of the "onenand is
> a totally different thing" model, in an independent context.
> 
> > Either way, are you OK with current state of the patch?
> 
> I won't block it.
> 
> -Scott

Ok, I'll queue this patchset and submit to Albert when I re-add the PXA250 
support to start.S (done already, but I need to test it).

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2011-11-05 22:40 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-31 13:23 [U-Boot] [PATCH 0/4] Voipac PXA270 OneNAND SPL Marek Vasut
2011-10-31 13:23 ` [U-Boot] [PATCH 1/4] PXA: Drop Voipac PXA270 OneNAND IPL Marek Vasut
2011-10-31 13:23 ` [U-Boot] [PATCH 2/4] PXA: Rework start.S to be closer to other ARMs Marek Vasut
2011-11-01 22:53   ` [U-Boot] [PATCH 2/4 V2] " Marek Vasut
2011-11-02  9:01   ` [U-Boot] [PATCH 2/4] " Stefan Herbrechtsmeier
2011-11-02 10:25     ` Marek Vasut
2011-11-02 10:53       ` Stefan Herbrechtsmeier
2011-10-31 13:23 ` [U-Boot] [PATCH 3/4] OneNAND: Add simple OneNAND SPL Marek Vasut
2011-10-31 23:15   ` Scott Wood
2011-11-01 22:54   ` [U-Boot] [PATCH 3/4 V2] " Marek Vasut
2011-11-02 22:41     ` Scott Wood
2011-11-03  0:15       ` Marek Vasut
2011-11-03  0:36         ` Kyungmin Park
2011-11-03  0:59           ` Marek Vasut
2011-11-03 16:19         ` Scott Wood
2011-11-03 16:56           ` Marek Vasut
2011-11-03 17:06             ` Scott Wood
2011-11-03 17:25               ` Marek Vasut
2011-11-03  1:55     ` [U-Boot] [PATCH 3/4 V3] " Marek Vasut
2011-11-03 21:59       ` [U-Boot] [PATCH 3/4 V4] " Marek Vasut
2011-10-31 13:23 ` [U-Boot] [PATCH 4/4] PXA: Adapt Voipac PXA270 to " Marek Vasut
2011-10-31 23:03   ` Scott Wood
2011-11-01 22:12     ` Marek Vasut
2011-11-01 22:34       ` Scott Wood
2011-11-01 22:44         ` Marek Vasut
2011-11-02 22:18           ` Scott Wood
2011-11-01 22:54   ` [U-Boot] [PATCH 4/4 V2] " Marek Vasut
2011-11-02 22:23     ` Scott Wood
2011-11-03  1:56     ` [U-Boot] [PATCH 4/4 V3] " Marek Vasut
2011-11-03 18:09       ` Scott Wood
2011-11-03 21:52         ` Marek Vasut
2011-11-03 22:20           ` Scott Wood
2011-11-04  0:55             ` Marek Vasut
2011-11-04 16:37               ` Scott Wood
2011-11-04 20:07                 ` Marek Vasut
2011-11-04 20:13                   ` Scott Wood
2011-11-04 20:31                     ` Marek Vasut
2011-11-05 22:40                     ` Marek Vasut

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox