From 17627f960589ffd1052804fa0837492bebfce2f1 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Tue, 28 Jul 2009 17:27:25 +0900 Subject: [PATCH] s5pc110: OneNAND IPL support Signed-off-by: Kyungmin Park --- onenand_ipl/onenand_boot.c | 9 +++++++++ onenand_ipl/onenand_ipl.h | 12 +++++------- onenand_ipl/onenand_read.c | 24 ++++++++++++++++++------ 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/onenand_ipl/onenand_boot.c b/onenand_ipl/onenand_boot.c index 63995ce..bd1285a 100644 --- a/onenand_ipl/onenand_boot.c +++ b/onenand_ipl/onenand_boot.c @@ -25,6 +25,8 @@ #include #include +#include +#include #include "onenand_ipl.h" @@ -33,11 +35,18 @@ typedef int (init_fnc_t)(void); void start_oneboot(void) { uchar *buf; + unsigned int value; buf = (uchar *) CONFIG_SYS_LOAD_ADDR; +#if 0 + value = readl(0xE0200000 + S5PC110_GPIO_J4_OFFSET + S5PC1XX_GPIO_DAT_OFFSET); + value |= (1 << 4); + writel(value, 0xE0200000 + S5PC110_GPIO_J4_OFFSET + S5PC1XX_GPIO_DAT_OFFSET); +#endif onenand_read_block(buf); + ((init_fnc_t *)CONFIG_SYS_LOAD_ADDR)(); /* should never come here */ diff --git a/onenand_ipl/onenand_ipl.h b/onenand_ipl/onenand_ipl.h index 2388c63..c6823f2 100644 --- a/onenand_ipl/onenand_ipl.h +++ b/onenand_ipl/onenand_ipl.h @@ -31,14 +31,12 @@ #define READ_INTERRUPT() \ onenand_readw(THIS_ONENAND(ONENAND_REG_INTERRUPT)) -#ifdef CONFIG_S5PC1XX -#define AHB_ADDR 0xB0000000 +/* S5PC100 specific */ +#define S5PC100_AHB_ADDR 0xB0000000 #define MEM_ADDR(fba, fpa, fsa) ((fba) << 13 | (fpa) << 7 | (fsa) << 5) -#define CMD_MAP_01(mem_addr) (AHB_ADDR | (1 << 26) | (mem_addr)) -#define CMD_MAP_11(addr) (AHB_ADDR | (3 << 26) | ((addr) << 2)) -#undef onenand_readw -#define onenand_readw(a) (readl(CMD_MAP_11((a) >> 1)) & 0xffff) -#endif +#define CMD_MAP_01(mem_addr) (S5PC100_AHB_ADDR | (1 << 26) | (mem_addr)) +#define CMD_MAP_11(addr) (S5PC100_AHB_ADDR | (3 << 26) | ((addr) << 2)) +#define onenand_ahb_readw(a) (readl(CMD_MAP_11((a) >> 1)) & 0xffff) extern int onenand_read_block(unsigned char *buf); #endif diff --git a/onenand_ipl/onenand_read.c b/onenand_ipl/onenand_read.c index ab654d0..ade3773 100644 --- a/onenand_ipl/onenand_read.c +++ b/onenand_ipl/onenand_read.c @@ -37,8 +37,10 @@ extern void *memcpy32(void *dest, void *src, int size); #endif -#ifdef CONFIG_S5PC1XX -static inline int onenand_read_page(ulong block, ulong page, +static int (*onenand_read_page)(ulong block, ulong page, + u_char *buf, int pagesize); + +static int s5pc100_onenand_read_page(ulong block, ulong page, u_char * buf, int pagesize) { unsigned int *p = (unsigned int *) buf; @@ -53,9 +55,9 @@ static inline int onenand_read_page(ulong block, ulong page, return 0; } -#else + /* read a page with ECC */ -static inline int onenand_read_page(ulong block, ulong page, +static int generic_onenand_read_page(ulong block, ulong page, u_char * buf, int pagesize) { unsigned long *base; @@ -105,7 +107,6 @@ static inline int onenand_read_page(ulong block, ulong page, return 0; } -#endif #ifndef CONFIG_ONENAND_START_PAGE #define CONFIG_ONENAND_START_PAGE 1 @@ -123,8 +124,19 @@ int onenand_read_block(unsigned char *buf) int page = CONFIG_ONENAND_START_PAGE, offset = 0; int pagesize = 0, erase_shift = 0; int erasesize = 0, nblocks = 0; + int mlc = 0; + + if ((readl(0xE0000000) & 0x00FFF000) == 0x00110000) { + onenand_read_page = generic_onenand_read_page; + if (onenand_readw(ONENAND_REG_TECHNOLOGY)) + mlc = 1; + } else { + onenand_read_page = s5pc100_onenand_read_page; + if (onenand_ahb_readw(ONENAND_REG_TECHNOLOGY)) + mlc = 1; + } - if (onenand_readw(ONENAND_REG_TECHNOLOGY)) { + if (mlc) { pagesize = 4096; /* MLC OneNAND has 4KiB pagesize */ erase_shift = 18; } else { -- 2.7.4