s5pc110: OneNAND IPL support
authorKyungmin Park <kyungmin.park@samsung.com>
Tue, 28 Jul 2009 08:27:25 +0000 (17:27 +0900)
committerKyungmin Park <kyungmin.park@samsung.com>
Tue, 28 Jul 2009 08:27:25 +0000 (17:27 +0900)
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
onenand_ipl/onenand_boot.c
onenand_ipl/onenand_ipl.h
onenand_ipl/onenand_read.c

index 63995ce..bd1285a 100644 (file)
@@ -25,6 +25,8 @@
 
 #include <common.h>
 #include <version.h>
+#include <asm/io.h>
+#include <asm/arch/gpio.h>
 
 #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 */
index 2388c63..c6823f2 100644 (file)
 #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
index ab654d0..ade3773 100644 (file)
 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 {