OneNAND Initial Program Loader (IPL) support

This patch enables the OneNAND boot within U-Boot.
Before this work, we used another OneNAND IPL called X-Loader based
on open source. With this work, we can build the oneboot.bin image
without other program.

The build sequence is simple.
First, it compiles the u-boot.bin
Second, it compiles OneNAND IPL
Finally, it becomes the oneboot.bin from OneNAND IPL and u-boot.bin
The mechanism is similar with NAND boot except it boots from itself.

Another thing is that you can only use the OneNAND IPL only to work
other bootloader such as RedBoot and so on.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
This commit is contained in:
Kyungmin Park 2008-01-17 16:43:25 +09:00 committed by Wolfgang Denk
parent 21f6f9636f
commit 751b9b5189
11 changed files with 698 additions and 2 deletions

View File

@ -274,13 +274,18 @@ NAND_SPL = nand_spl
U_BOOT_NAND = $(obj)u-boot-nand.bin
endif
ifeq ($(CONFIG_ONENAND_U_BOOT),y)
ONENAND_IPL = onenand_ipl
U_BOOT_ONENAND = $(obj)u-boot-onenand.bin
endif
__OBJS := $(subst $(obj),,$(OBJS))
__LIBS := $(subst $(obj),,$(LIBS))
#########################################################################
#########################################################################
ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)
ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND)
all: $(ALL)
@ -327,6 +332,12 @@ $(NAND_SPL): $(VERSION_FILE) $(obj)include/autoconf.mk
$(U_BOOT_NAND): $(NAND_SPL) $(obj)u-boot.bin $(obj)include/autoconf.mk
cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin
$(ONENAND_IPL): $(VERSION_FILE) $(obj)include/autoconf.mk
$(MAKE) -C onenand_ipl/board/$(BOARDDIR) all
$(U_BOOT_ONENAND): $(ONENAND_IPL) $(obj)u-boot.bin $(obj)include/autoconf.mk
cat $(obj)onenand_ipl/onenand-ipl-2k.bin $(obj)u-boot.bin > $(obj)u-boot-onenand.bin
$(VERSION_FILE):
@( echo -n "#define U_BOOT_VERSION \"U-Boot " ; \
echo -n "$(U_BOOT_VERSION)" ; \
@ -2597,7 +2608,9 @@ omap2420h4_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm1136 omap2420h4
apollon_config : unconfig
@echo "#define CONFIG_ONENAND_U_BOOT" > $(obj)include/config.h
@$(MKCONFIG) $(@:_config=) arm arm1136 apollon
@echo "CONFIG_ONENAND_U_BOOT = y" >> $(obj)include/config.mk
#========================================================================
# i386
@ -2898,6 +2911,8 @@ clean:
@rm -f $(obj)board/bf537-stamp/u-boot.lds $(obj)board/bf561-ezkit/u-boot.lds
@rm -f $(obj)include/bmp_logo.h
@rm -f $(obj)nand_spl/u-boot-spl $(obj)nand_spl/u-boot-spl.map
@rm -f $(obj)onenand_ipl/onenand-ipl $(obj)onenand_ipl/onenand-ipl.bin \
$(obj)onenand_ipl/onenand-ipl-2k.bin $(obj)onenand_ipl/onenand-ipl.map
@rm -f $(obj)api_examples/demo $(VERSION_FILE)
clobber: clean
@ -2912,6 +2927,7 @@ clobber: clean
@rm -f $(obj)tools/inca-swap-bytes $(obj)cpu/mpc824x/bedbug_603e.c
@rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f
@[ ! -d $(obj)onenand_ipl ] || find $(obj)onenand_ipl -lname "*" -print | xargs rm -f
@[ ! -d $(obj)api_examples ] || find $(obj)api_examples -lname "*" -print | xargs rm -f
ifeq ($(OBJTREE),$(SRCTREE))

View File

@ -440,7 +440,8 @@ void muxSetupTouchScreen(void)
void muxSetupGPMC(void)
{
/* gpmc_io_dir, MCR */
writel(0x4800008C, 0x19000000);
volatile unsigned int *MCR = (unsigned int *) 0x4800008C;
*MCR = 0x19000000;
/* NOR FLASH CS0 */
/* signal - Gpmc_clk; pin - J4; offset - 0x0088; mode 0; Byte-3 */

View File

@ -35,6 +35,25 @@
#endif
.globl _start
_start: b reset
#ifdef CONFIG_ONENAND_IPL
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
_hang:
.word do_hang
.word 0x12345678
.word 0x12345678
.word 0x12345678
.word 0x12345678
.word 0x12345678
.word 0x12345678
.word 0x12345678 /* now 16*4=64 */
#else
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
@ -51,6 +70,7 @@ _not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
_pad: .word 0x12345678 /* now 16*4=64 */
#endif /* CONFIG_ONENAND_IPL */
.global _end_vect
_end_vect:
@ -139,7 +159,9 @@ relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
#ifndef CONFIG_ONENAND_IPL
beq stack_setup
#endif /* CONFIG_ONENAND_IPL */
ldr r2, _armboot_start
ldr r3, _bss_start
@ -156,26 +178,36 @@ copy_loop:
/* Set up the stack */
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
#ifdef CONFIG_ONENAND_IPL
sub sp, r0, #128 /* leave 32 words for abort-stack */
#else
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
#endif /* CONFIG_ONENAND_IPL */
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
#ifndef CONFIG_ONENAND_IPL
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
#endif
ldr pc, _start_armboot
#ifdef CONFIG_ONENAND_IPL
_start_armboot: .word start_oneboot
#else
_start_armboot: .word start_armboot
#endif
/*
@ -214,6 +246,8 @@ cpu_init_crit:
bl lowlevel_init /* go setup pll,mux,memory */
mov lr, ip /* restore link */
mov pc, lr /* back to my caller */
#ifndef CONFIG_ONENAND_IPL
/*
*************************************************************************
*
@ -326,10 +360,17 @@ cpu_init_crit:
.macro get_fiq_stack @ setup FIQ stack
ldr sp, FIQ_STACK_START
.endm
#endif /* CONFIG_ONENAND_IPL */
/*
* exception handlers
*/
#ifdef CONFIG_ONENAND_IPL
.align 5
do_hang:
ldr sp, _TEXT_BASE /* use 32 words about stack */
bl hang /* hang and never return */
#else /* !CONFIG_ONENAND IPL */
.align 5
undefined_instruction:
get_bad_stack
@ -415,3 +456,4 @@ rstctl:
.word PM_RSTCTRL_WKUP
#endif
#endif /* CONFIG_ONENAND_IPL */

View File

@ -0,0 +1,65 @@
include $(TOPDIR)/config.mk
include $(TOPDIR)/include/config.mk
include $(TOPDIR)/onenand_ipl/board/$(BOARDDIR)/config.mk
LDSCRIPT= $(TOPDIR)/onenand_ipl/board/$(BOARDDIR)/u-boot.onenand.lds
LDFLAGS = -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
AFLAGS += -DCONFIG_ONENAND_IPL
CFLAGS += -DCONFIG_ONENAND_IPL
OBJCLFAGS += --gap-fill=0x00
SOBJS = start.o low_levelinit.o # _memcpy32.o
COBJS = apollon.o onenand_read.o 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=0x800 -O binary $< $@
$(onenandobj)onenand-ipl.bin: $(onenandobj)onenand-ipl
$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
$(onenandobj)onenand-ipl: $(OBJS)
cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
-Map $(onenandobj)onenand-ipl.map \
-o $(onenandobj)onenand-ipl
# create symbolic links from common files
# from cpu directory
$(obj)start.S:
rm -f $(obj)start.S
ln -s $(SRCTREE)/cpu/$(CPU)/start.S $(obj)start.S
# from onenand_ipl directory
$(obj)onenand_ipl.h:
rm -f $(obj)onenand_ipl.h
ln -s $(SRCTREE)/onenand_ipl/onenand_ipl.h $(obj)onenand_ipl.h
$(obj)onenand_boot.c: $(obj)onenand_ipl.h
rm -f $(obj)onenand_boot.c
ln -s $(SRCTREE)/onenand_ipl/onenand_boot.c $(obj)onenand_boot.c
$(obj)onenand_read.c: $(obj)onenand_ipl.h
rm -f $(obj)onenand_read.c
ln -s $(SRCTREE)/onenand_ipl/onenand_read.c $(obj)onenand_read.c
$(obj)%.o: $(obj)%.S
$(CC) $(AFLAGS) -c -o $@ $<
$(obj)%.o: $(obj)$.c
$(CC) $(CFLAGS) -c -o $@ $<
include $(SRCTREE)/rules.mk
sinclude $(obj).depend

View File

@ -0,0 +1,70 @@
/*
* (C) Copyright 2005-2008 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/arch/mux.h>
#define write_config_reg(reg, value) \
do { \
writeb(value, reg); \
} while (0)
/*****************************************
* Routine: board_init
* Description: Early hardware init.
*****************************************/
int board_init(void)
{
return 0;
}
#ifdef CFG_PRINTF
/* Pin Muxing registers used for UART1 */
/****************************************
* Routine: muxSetupUART1 (ostboot)
* Description: Set up uart1 muxing
*****************************************/
static void muxSetupUART1(void)
{
/* UART1_CTS pin configuration, PIN = D21 */
write_config_reg(CONTROL_PADCONF_UART1_CTS, 0);
/* UART1_RTS pin configuration, PIN = H21 */
write_config_reg(CONTROL_PADCONF_UART1_RTS, 0);
/* UART1_TX pin configuration, PIN = L20 */
write_config_reg(CONTROL_PADCONF_UART1_TX, 0);
/* UART1_RX pin configuration, PIN = T21 */
write_config_reg(CONTROL_PADCONF_UART1_RX, 0);
}
#endif
/**********************************************************
* Routine: s_init
* Description: Does early system init of muxing and clocks.
* - Called at time when only stack is available.
**********************************************************/
int s_init(int skip)
{
#ifdef CFG_PRINTF
muxSetupUART1();
#endif
return 0;
}

View File

@ -0,0 +1,14 @@
#
# (C) Copyright 2005-2008 Samsung Electronics
# Kyungmin Park <kyungmin.park@samsung.com>
#
# Samsung Apollon board with OMAP2420 (ARM1136) cpu
#
# Apollon has 1 bank of 128MB mDDR-SDRAM on CS0
# Physical Address:
# 8000'0000 (bank0)
# 8800'0000 (bank1)
# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000
# (mem base + reserved)
TEXT_BASE = 0x00000000

View File

@ -0,0 +1,205 @@
/*
* Board specific setup info
*
* (C) Copyright 2005-2008 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
*
* Derived from board/omap2420h4/platform.S
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <config.h>
#include <asm/arch/omap2420.h>
#include <asm/arch/mem.h>
#include <asm/arch/clocks.h>
#define APOLLON_CS0_BASE 0x00000000
#ifdef PRCM_CONFIG_I
#define SDRC_ACTIM_CTRLA_0_VAL 0x7BA35907
#define SDRC_ACTIM_CTRLB_0_VAL 0x00000013
#define SDRC_RFR_CTRL_0_VAL 0x00044C01
/* GPMC */
#define APOLLON_GPMC_CONFIG1_0 0xe30d1201
#define APOLLON_GPMC_CONFIG2_0 0x000c1000
#define APOLLON_GPMC_CONFIG3_0 0x00030400
#define APOLLON_GPMC_CONFIG4_0 0x0B841006
#define APOLLON_GPMC_CONFIG5_0 0x020F0C11
#define APOLLON_GPMC_CONFIG6_0 0x00000000
#define APOLLON_GPMC_CONFIG7_0 (0x00000e40 | (APOLLON_CS0_BASE >> 24))
#elif defined(PRCM_CONFIG_II)
#define SDRC_ACTIM_CTRLA_0_VAL 0x4A59B485
#define SDRC_ACTIM_CTRLB_0_VAL 0x0000000C
#define SDRC_RFR_CTRL_0_VAL 0x00030001
/* GPMC */
#define APOLLON_GPMC_CONFIG1_0 0xe30d1201
#define APOLLON_GPMC_CONFIG2_0 0x00080E81
#define APOLLON_GPMC_CONFIG3_0 0x00030400
#define APOLLON_GPMC_CONFIG4_0 0x08041586
#define APOLLON_GPMC_CONFIG5_0 0x020C090E
#define APOLLON_GPMC_CONFIG6_0 0x00000000
#define APOLLON_GPMC_CONFIG7_0 (0x00000e40 | (APOLLON_CS0_BASE >> 24))
#else
#error "Please configure PRCM schecm"
#endif
_TEXT_BASE:
.word TEXT_BASE /* sdram load addr from config.mk */
.globl lowlevel_init
lowlevel_init:
mov r3, r0 /* save skip information */
/* Disable watchdog */
ldr r0, =WD2_BASE
ldr r1, =WD_UNLOCK1
str r1, [r0, #WSPR]
ldr r1, =WD_UNLOCK2
str r1, [r0, #WSPR]
#ifdef DEBUG_LED
/* LED0 OFF */
ldr r0, =0x480000E5 /* ball AA10, mode 3 */
mov r1, #0x0b
strb r1, [r0]
#endif
/* Pin muxing for SDRC */
mov r1, #0x00
ldr r0, =0x480000A1 /* ball C12, mode 0 */
strb r1, [r0]
ldr r0, =0x48000032 /* ball D11, mode 0 */
strb r1, [r0]
ldr r0, =0x480000A3 /* ball B13, mode 0 */
strb r1, [r0]
/* SDRC setting */
ldr r0, =OMAP2420_SDRC_BASE
ldr r1, =0x00000010
str r1, [r0, #0x10]
ldr r1, =0x00000100
str r1, [r0, #0x44]
/* SDRC CS0 configuration */
#ifdef CONFIG_APOLLON_PLUS
ldr r1, =0x01702011
#else
ldr r1, =0x00d04011
#endif
str r1, [r0, #0x80]
ldr r1, =SDRC_ACTIM_CTRLA_0_VAL
str r1, [r0, #0x9C]
ldr r1, =SDRC_ACTIM_CTRLB_0_VAL
str r1, [r0, #0xA0]
ldr r1, =SDRC_RFR_CTRL_0_VAL
str r1, [r0, #0xA4]
ldr r1, =0x00000041
str r1, [r0, #0x70]
/* Manual command sequence */
ldr r1, =0x00000007
str r1, [r0, #0xA8]
ldr r1, =0x00000000
str r1, [r0, #0xA8]
ldr r1, =0x00000001
str r1, [r0, #0xA8]
ldr r1, =0x00000002
str r1, [r0, #0xA8]
str r1, [r0, #0xA8]
/*
* CS0 SDRC Mode register
* Burst length = 4 - DDR memory
* Serial mode
* CAS latency = 3
*/
ldr r1, =0x00000032
str r1, [r0, #0x84]
/* Note: You MUST set EMR values */
/* EMR1 & EMR2 */
ldr r1, =0x00000000
str r1, [r0, #0x88]
str r1, [r0, #0x8C]
#ifdef OLD_SDRC_DLLA_CTRL
/* SDRC_DLLA_CTRL */
ldr r1, =0x00007306
str r1, [r0, #0x60]
ldr r1, =0x00007303
str r1, [r0, #0x60]
#else
/* SDRC_DLLA_CTRL */
ldr r1, =0x00000506
str r1, [r0, #0x60]
ldr r1, =0x00000503
str r1, [r0, #0x60]
#endif
#ifdef __BROKEN_FEATURE__
/* SDRC_DLLB_CTRL */
ldr r1, =0x00000506
str r1, [r0, #0x68]
ldr r1, =0x00000503
str r1, [r0, #0x68]
#endif
/* little delay after init */
mov r2, #0x1800
1:
subs r2, r2, #0x1
bne 1b
ldr sp, SRAM_STACK
str ip, [sp] /* stash old link register */
mov ip, lr /* save link reg across call */
mov r0, r3 /* pass skip info to s_init */
bl s_init /* go setup pll,mux,memory */
ldr ip, [sp] /* restore save ip */
mov lr, ip /* restore link reg */
/* back to arch calling code */
mov pc, lr
/* the literal pools origin */
.ltorg
SRAM_STACK:
.word LOW_LEVEL_SRAM_STACK

View File

@ -0,0 +1,53 @@
/*
* (C) Copyright 2005-2008 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
*
* Derived from X-loader
*
* 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 : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}

View File

@ -0,0 +1,81 @@
/*
* (C) Copyright 2005-2008 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
*
* Derived from x-loader
*
* 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 <version.h>
#include "onenand_ipl.h"
#ifdef CFG_PRINTF
int print_info(void)
{
printf(XLOADER_VERSION);
return 0;
}
#endif
typedef int (init_fnc_t)(void);
init_fnc_t *init_sequence[] = {
board_init, /* basic board dependent setup */
#ifdef CFG_PRINTF
serial_init, /* serial communications setup */
print_info,
#endif
NULL,
};
void start_oneboot(void)
{
init_fnc_t **init_fnc_ptr;
uchar *buf;
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0)
hang();
}
buf = (uchar *) CFG_LOAD_ADDR;
if (!onenand_read_block(buf, ONENAND_START_BLOCK))
buf += ONENAND_BLOCK_SIZE;
if (buf == (uchar *)CFG_LOAD_ADDR)
hang();
/* go run U-Boot and never return */
printf("Starting OS Bootloader...\n");
((init_fnc_t *)CFG_LOAD_ADDR)();
/* should never come here */
}
void hang(void)
{
/* if board_hang() returns, hange here */
printf("X-Loader hangs\n");
for (;;);
}

44
onenand_ipl/onenand_ipl.h Normal file
View File

@ -0,0 +1,44 @@
/*
* (C) Copyright 2005-2008 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef _ONENAND_IPL_H
#define _ONENAND_IPL_H
#include <linux/mtd/onenand_regs.h>
#define ONENAND_START_BLOCK 0
#define ONENAND_BLOCK_SIZE 2048
#ifndef CFG_PRINTF
#define printf(format, args...)
#endif
#define onenand_readw(a) readw(a)
#define onenand_writew(v, a) writew(v, a)
#define THIS_ONENAND(a) (CFG_ONENAND_BASE + (a))
#define READ_INTERRUPT() \
onenand_readw(THIS_ONENAND(ONENAND_REG_INTERRUPT))
#define ONENAND_PAGE_SIZE 2048
extern int onenand_read_block(unsigned char *buf, ulong block);
#endif

105
onenand_ipl/onenand_read.c Normal file
View File

@ -0,0 +1,105 @@
/*
* (C) Copyright 2005-2008 Samsung Electronis
* 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 <asm/string.h>
#include "onenand_ipl.h"
#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)
/* read a page with ECC */
static inline int onenand_read_page(ulong block, ulong page, u_char *buf)
{
unsigned long *base;
#ifndef __HAVE_ARCH_MEMCPY32
unsigned int offset, value;
unsigned long *p;
#endif
onenand_writew(onenand_block_address(block),
THIS_ONENAND(ONENAND_REG_START_ADDRESS1));
onenand_writew(onenand_sector_address(page),
THIS_ONENAND(ONENAND_REG_START_ADDRESS8));
onenand_writew(onenand_buffer_address(),
THIS_ONENAND(ONENAND_REG_START_BUFFER));
onenand_writew(onenand_bufferram_address(block),
THIS_ONENAND(ONENAND_REG_START_ADDRESS2));
onenand_writew(ONENAND_INT_CLEAR, THIS_ONENAND(ONENAND_REG_INTERRUPT));
onenand_writew(ONENAND_CMD_READ, THIS_ONENAND(ONENAND_REG_COMMAND));
#ifndef __HAVE_ARCH_MEMCPY32
p = (unsigned long *) buf;
#endif
base = (unsigned long *) (CFG_ONENAND_BASE + ONENAND_DATARAM);
while (!(READ_INTERRUPT() & ONENAND_INT_READ))
continue;
#ifdef __HAVE_ARCH_MEMCPY32
/* 32 bytes boundary memory copy */
memcpy32(buf, base, ONENAND_PAGE_SIZE);
#else
for (offset = 0; offset < (ONENAND_PAGE_SIZE >> 2); offset++) {
value = *(base + offset);
*p++ = value;
}
#endif
return 0;
}
#define ONENAND_START_PAGE 1
#define ONENAND_PAGES_PER_BLOCK 64
/**
* onenand_read_block - Read a block data to buf
* @return 0 on success
*/
int onenand_read_block(unsigned char *buf, ulong block)
{
int page, offset = 0;
/* NOTE: you must read page from page 1 of block 0 */
/* read the block page by page*/
for (page = ONENAND_START_PAGE;
page < ONENAND_PAGES_PER_BLOCK; page++) {
onenand_read_page(block, page, buf + offset);
offset += ONENAND_PAGE_SIZE;
}
return 0;
}