]> code.ossystems Code Review - openembedded-core.git/commitdiff
u-boot: import OpenMoko uboot from OE
authorMarcin Juszkiewicz <hrw@openedhand.com>
Mon, 29 Oct 2007 11:00:19 +0000 (11:00 +0000)
committerMarcin Juszkiewicz <hrw@openedhand.com>
Mon, 29 Oct 2007 11:00:19 +0000 (11:00 +0000)
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@3014 311d38ba-8fff-0310-9ca6-ca027cbcb966

63 files changed:
meta/packages/uboot/u-boot-mkimage-gta01-native_svn.bb [deleted file]
meta/packages/uboot/u-boot-mkimage-openmoko-native/bbt-create-optional.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/bbt-scan-second.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/boot-from-ram-and-nand.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/boot-from-ram-reloc.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/boot-menu.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/cmd-unzip.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/console-ansi.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/default-env.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/dontask.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/dynenv-harden.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/early-powerdown.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/enable-splash-bmp.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/env_nand_oob.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/ext2load_hex.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/lowlevel_foo.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/makefile-no-dirafter.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/mmcinit-power-up.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-badisbad.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-createbbt.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-dynamic_partitions.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-otp.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-read_write_oob.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/neo1973-chargefast.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/preboot-override.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/raise-limits.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/series [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/splashimage-command.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-20061030-neo1973.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-20061030-qt2410.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-arm920_s3c2410_irq_demux.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-arm920t-gd_in_irq.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-bbt-quiet.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-cmd_s3c2410.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-cramfs_but_no_jffs2.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-dfu.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-gta02.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-hxd8.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-license.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-machtypes.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-mokoversion.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-nand-markbad-reallybad.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-neo1973-defaultenv.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-neo1973-resume.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-misccr-definitions.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-mmc.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-nand.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-norelocate_irqvec_cpy.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-warnings-fix.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410_fb.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410_udc.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2440.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2443.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-smdk2440.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-smdk2443.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-strtoul.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-usbtty-acm.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/unbusy-i2c.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/usbdcore-multiple_configs.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native/wakeup-reason-nand-only.patch [new file with mode: 0644]
meta/packages/uboot/u-boot-mkimage-openmoko-native_oe.bb [new file with mode: 0644]
meta/packages/uboot/uboot-gta01_svn.bb [deleted file]
meta/packages/uboot/uboot-openmoko_svn.bb [new file with mode: 0644]

diff --git a/meta/packages/uboot/u-boot-mkimage-gta01-native_svn.bb b/meta/packages/uboot/u-boot-mkimage-gta01-native_svn.bb
deleted file mode 100644 (file)
index 7c10d65..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-require uboot-gta01_svn.bb
-
-PROVIDES = ""
-TARGET_LDFLAGS = ""
-
-do_compile () {
-       chmod +x board/neo1973/gta01/split_by_variant.sh
-       oe_runmake gta01bv3_config
-       oe_runmake clean
-       oe_runmake tools
-}
-
-do_deploy () {
-       install -m 0755 tools/mkimage ${STAGING_BINDIR_NATIVE}/uboot-mkimage
-}
-
-do_deploy[dirs] = "${S}"
-addtask deploy before do_package after do_install
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/bbt-create-optional.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/bbt-create-optional.patch
new file mode 100644 (file)
index 0000000..d7a2a87
--- /dev/null
@@ -0,0 +1,52 @@
+This patch makes creation of the BBT optional for the s3c24x0 platform.
+It adds:
+
+- a new platform-independent NAND-wide flag NAND_DONT_CREATE_BBT
+- one user of this flag, namely s3c24x0
+
+Experimental.
+
+- Werner Almesberger <werner@openmoko.org>
+
+
+Index: u-boot/cpu/arm920t/s3c24x0/nand.c
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/nand.c     2007-02-16 23:53:29.000000000 +0100
++++ u-boot/cpu/arm920t/s3c24x0/nand.c  2007-02-16 23:53:54.000000000 +0100
+@@ -169,7 +169,7 @@
+       nand->eccmode = NAND_ECC_SOFT;
+ #ifdef CONFIG_S3C2410_NAND_BBT
+-      nand->options = NAND_USE_FLASH_BBT;
++      nand->options = NAND_USE_FLASH_BBT | NAND_DONT_CREATE_BBT;
+ #else
+       nand->options = 0;
+ #endif
+Index: u-boot/drivers/nand/nand_bbt.c
+===================================================================
+--- u-boot.orig/drivers/nand/nand_bbt.c        2007-02-16 23:53:36.000000000 +0100
++++ u-boot/drivers/nand/nand_bbt.c     2007-02-16 23:53:54.000000000 +0100
+@@ -678,7 +678,8 @@
+               }
+ create:
+               /* Create the bad block table by scanning the device ? */
+-              if (!(td->options & NAND_BBT_CREATE))
++              if (!(td->options & NAND_BBT_CREATE) ||
++                (this->options & NAND_DONT_CREATE_BBT))
+                       continue;
+               /* Create the table in memory by scanning the chip(s) */
+Index: u-boot/include/linux/mtd/nand.h
+===================================================================
+--- u-boot.orig/include/linux/mtd/nand.h       2007-02-16 23:53:08.000000000 +0100
++++ u-boot/include/linux/mtd/nand.h    2007-02-16 23:53:54.000000000 +0100
+@@ -187,7 +187,8 @@
+  * This can only work if we have the ecc bytes directly behind the
+  * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */
+ #define NAND_HWECC_SYNDROME   0x00020000
+-
++/* Do not create an BBT if none is found. Overrides NAND_BBT_CREATE. */
++#define NAND_DONT_CREATE_BBT  0x00040000
+ /* Options set by nand scan */
+ /* Nand scan has allocated oob_buf */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/bbt-scan-second.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/bbt-scan-second.patch
new file mode 100644 (file)
index 0000000..37b2807
--- /dev/null
@@ -0,0 +1,69 @@
+Scan also the second OOB page for bad block information.
+
+board/neo1973/gta01/nand.c (board_nand_init): added board-specific badblock
+  pattern which sets NAND_BBT_SCAN2NDPAGE
+drivers/nand/nand_base.c (nand_block_bad): also consider the second page in a
+  block if NAND_BBT_SCAN2NDPAGE is set
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/board/neo1973/gta01/nand.c
+===================================================================
+--- u-boot.orig/board/neo1973/gta01/nand.c
++++ u-boot/board/neo1973/gta01/nand.c
+@@ -113,9 +113,23 @@
+ }
++/* Derived from drivers/nand/nand_bbt.c:smallpage_flashbased */
++
++static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
++
++static struct nand_bbt_descr badblock_pattern = {
++      .options =
++          NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES | NAND_BBT_SCAN2NDPAGE,
++      .offs = 5,
++      .len = 1,
++      .pattern = scan_ff_pattern
++};
++
++
+ int board_nand_init(struct nand_chip *nand)
+ {
+       nand->read_otp = samsung_nand_read_otp;
+       nand->write_otp = samsung_nand_write_otp;
++      nand->badblock_pattern = &badblock_pattern;
+       return s3c24x0_nand_init(nand);
+ }
+Index: u-boot/drivers/nand/nand_base.c
+===================================================================
+--- u-boot.orig/drivers/nand/nand_base.c
++++ u-boot/drivers/nand/nand_base.c
+@@ -421,7 +421,7 @@
+  *
+  * Check, if the block is bad.
+  */
+-static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
++static int nand_block_bad_page(struct mtd_info *mtd, loff_t ofs, int getchip)
+ {
+       int page, chipnr, res = 0;
+       struct nand_chip *this = mtd->priv;
+@@ -460,6 +460,18 @@
+       return res;
+ }
++static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
++{
++      struct nand_chip *this = mtd->priv;
++
++      if (nand_block_bad_page(mtd, ofs, getchip))
++              return 1;
++      if (this->badblock_pattern->options & NAND_BBT_SCAN2NDPAGE &&
++          nand_block_bad_page(mtd, ofs+(1 << this->page_shift), getchip))
++              return 1;
++      return 0;
++}
++
+ /**
+  * nand_default_block_markbad - [DEFAULT] mark a block bad
+  * @mtd:      MTD device structure
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/boot-from-ram-and-nand.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/boot-from-ram-and-nand.patch
new file mode 100644 (file)
index 0000000..fa0de39
--- /dev/null
@@ -0,0 +1,98 @@
+Auto-detect whether we're booting from RAM or NAND, and act accordingly. This
+allows us to use the same u-boot binary for all boot modes.
+
+include/configs/neo1973.h: introduced new config option
+  CONFIG_LL_INIT_NAND_ONLY to perform low-level initialization only when
+  booting from NAND
+include/configs/neo1973.h: got rid of BUILD_FOR_RAM
+cpu/arm920t/start.S: detect if we need to boot from NAND at run time (i.e., if
+  we're running at address 0)
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/cpu/arm920t/start.S
+===================================================================
+--- u-boot.orig/cpu/arm920t/start.S
++++ u-boot/cpu/arm920t/start.S
+@@ -157,18 +157,26 @@
+       str     r1, [r0]
+ #endif        /* CONFIG_S3C2400 || CONFIG_S3C2410 */
+-      /*
+-       * we do sys-critical inits only at reboot,
+-       * not when booting from ram!
+-       */
+ #ifndef CONFIG_SKIP_LOWLEVEL_INIT
++#ifndef CONFIG_LL_INIT_NAND_ONLY
+       bl      cpu_init_crit
+ #endif
++#endif
+ #ifndef CONFIG_SKIP_RELOCATE_UBOOT
+-#ifndef CONFIG_S3C2410_NAND_BOOT
+-relocate:                             /* relocate U-Boot to RAM           */
+       adr     r0, _start              /* r0 <- current position of code   */
++
++#ifdef CONFIG_S3C2410_NAND_BOOT
++                                      /* are we running from NAND ?       */
++#define       BWSCON  0x48000000
++      ldr     r1, =BWSCON             /* Z = CPU booted from NAND         */
++      ldr     r1, [r1]
++      tst     r1, #6                  /* BWSCON[2:1] = OM[1:0]            */
++      teqeq   r0, #0                  /* Z &= running at address 0        */
++      beq     nand_load
++#endif /* CONFIG_S3C2410_NAND_BOOT */
++
++relocate:                             /* relocate U-Boot to RAM           */
+       ldr     r1, _TEXT_BASE          /* test if we run from flash or RAM */
+       cmp     r0, r1                  /* don't reloc during debug         */
+       beq     done_relocate
+@@ -188,10 +196,13 @@
+       ldr     pc, _done_relocate      /* jump to relocated code */
+ _done_relocate:
+       .word   done_relocate
+-done_relocate:
+-#else /* NAND_BOOT */
+-relocate:
+-copy_myself:
++
++#ifdef CONFIG_S3C2410_NAND_BOOT
++nand_load:
++#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && defined(CONFIG_LL_INIT_NAND_ONLY)
++      bl      cpu_init_crit
++#endif
++
+       /* mov  r10, lr */
+       @ reset NAND
+@@ -275,7 +286,8 @@
+ #endif
+ 1:    b       1b
+ done_nand_read:
+-#endif /* NAND_BOOT */
++#endif /* CONFIG_S3C2410_NAND_BOOT */
++done_relocate:
+ #endif /* CONFIG_SKIP_RELOCATE_UBOOT */
+       /* Set up the stack                                                 */
+Index: u-boot/include/configs/neo1973_gta01.h
+===================================================================
+--- u-boot.orig/include/configs/neo1973_gta01.h
++++ u-boot/include/configs/neo1973_gta01.h
+@@ -26,14 +26,10 @@
+ #ifndef __CONFIG_H
+ #define __CONFIG_H
+-#if defined(BUILD_FOR_RAM)
+-/* If we want to start u-boot from inside RAM */
+-#define CONFIG_SKIP_LOWLEVEL_INIT     1
+-#else
+-/* we want to start u-boot directly from within NAND flash */
++/* we want to be able to start u-boot directly from within NAND flash */
++#define CONFIG_LL_INIT_NAND_ONLY
+ #define CONFIG_S3C2410_NAND_BOOT      1
+ #define CONFIG_S3C2410_NAND_SKIP_BAD  1
+-#endif
+ #define CFG_UBOOT_SIZE                0x40000 /* size of u-boot, for NAND loading */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/boot-from-ram-reloc.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/boot-from-ram-reloc.patch
new file mode 100644 (file)
index 0000000..53a3e05
--- /dev/null
@@ -0,0 +1,62 @@
+This patch allows us to boot from anywhere in RAM. It mainly sets the stage
+for later patches. The only real changes here is the better handling of already
+cached code (e.g., if we were started by a previous instance of u-boot), and
+that we drop CONFIG_SKIP_RELOCATE_UBOOT from neo1973.h
+
+cpu/arm920t/start.S: if not relocating, instead of going straight to
+  stack_setup, jump to done_relocate, which may perform other setup tasks
+cpu/arm920t/start.S: after relocating, flush the cache and jump to the new code
+include/configs/neo1973.h: remove CONFIG_SKIP_RELOCATE_UBOOT
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/cpu/arm920t/start.S
+===================================================================
+--- u-boot.orig/cpu/arm920t/start.S
++++ u-boot/cpu/arm920t/start.S
+@@ -171,7 +171,7 @@ 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         */
+-      beq     stack_setup
++      beq     done_relocate
+       ldr     r2, _armboot_start
+       ldr     r3, _bss_start
+@@ -181,8 +181,14 @@ relocate:                         /* relocate U-Boot to RAM        
+ copy_loop:
+       ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */
+       stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */
+-      cmp     r0, r2                  /* until source end addreee [r2]    */
++      cmp     r0, r2                  /* until source end address [r2]    */
+       ble     copy_loop
++      mov     r0, #0                  /* flush v3/v4 cache */
++      mcr     p15, 0, r0, c7, c7, 0
++      ldr     pc, _done_relocate      /* jump to relocated code */
++_done_relocate:
++      .word   done_relocate
++done_relocate:
+ #else /* NAND_BOOT */
+ relocate:
+ copy_myself:
+@@ -270,7 +276,7 @@ notmatch:
+ 1:    b       1b
+ done_nand_read:
+ #endif /* NAND_BOOT */
+-#endif        /* CONFIG_SKIP_RELOCATE_UBOOT */
++#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
+       /* Set up the stack                                                 */
+ stack_setup:
+Index: u-boot/include/configs/neo1973_gta01.h
+===================================================================
+--- u-boot.orig/include/configs/neo1973_gta01.h
++++ u-boot/include/configs/neo1973_gta01.h
+@@ -28,7 +28,6 @@
+ #if defined(BUILD_FOR_RAM)
+ /* If we want to start u-boot from inside RAM */
+-#define CONFIG_SKIP_RELOCATE_UBOOT    1
+ #define CONFIG_SKIP_LOWLEVEL_INIT     1
+ #else
+ /* we want to start u-boot directly from within NAND flash */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/boot-menu.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/boot-menu.patch
new file mode 100644 (file)
index 0000000..352967a
--- /dev/null
@@ -0,0 +1,769 @@
+board/neo1973/bootmenu.c: simple configurable boot menu
+board/neo1973/neo1973.c (neo1973_new_second): return 1 if a new second has
+  started since the last call
+board/neo1973/neo1973.c (neo1973_on_key_pressed): return 1 if the $POWER key is
+  pressed
+board/neo1973/neo1973.c (board_late_init): make use of neo1973_new_second and
+  neo1973_on_key_pressed
+board/neo1973/neo1973.h: added function prototypes
+u-boot/board/neo1973/neo1973.c (board_late_init): enter the boot menu when 
+  "AUX" was pressed at least half the time
+u-boot/board/neo1973/neo1973.c (board_late_init): minor code cleanup
+u-boot/common/console.c, include/console.h: added "console_poll_hook" to be
+  called when waiting for console in put in "getc" and "tstc"
+board/neo1973/neo1973.c (board_late_init): poll for the boot menu also on RAM
+  boot, reset, or unknown cause
+board/neo1973/neo1973.c (board_late_init): don't look for the power key if
+  woken up by the charger
+board/neo1973/neo1973.h, board/neo1973/neo1973.c, board/neo1973/bootmenu.c:
+  renamed neo1973_911_key_pressed to neo1973_aux_key_pressed
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/board/neo1973/common/bootmenu.c
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/common/bootmenu.c
+@@ -0,0 +1,120 @@
++/*
++ * bootmenu.c - Boot menu
++ *
++ * Copyright (C) 2006-2007 by OpenMoko, Inc.
++ * Written by Werner Almesberger <werner@openmoko.org>
++ * All Rights Reserved
++ *
++ * 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.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
++ */
++
++
++#include <common.h>
++#include <environment.h>
++#include <bootmenu.h>
++#include <asm/atomic.h>
++
++#ifdef CONFIG_USBD_DFU
++#include "usbdcore.h"
++#include "usb_dfu.h"
++#endif
++
++#include "neo1973.h"
++
++
++#define DEBOUNCE_LOOPS                1000    /* wild guess */
++
++
++static int debounce(int (*fn)(void), int *last)
++{
++      int on, i;
++
++again:
++      on = fn();
++      if (on != *last)
++              for (i = DEBOUNCE_LOOPS; i; i--)
++                      if (on != fn())
++                              goto again;
++      *last = on;
++      return on;
++}
++
++
++static int aux_key(void *user)
++{
++      static int last_aux = -1;
++
++      return debounce(neo1973_aux_key_pressed, &last_aux);
++}
++
++
++static int on_key(void *user)
++{
++      static int last_on = -1;
++
++      return debounce(neo1973_on_key_pressed, &last_on);
++}
++
++
++static void factory_reset(void *user)
++{
++      default_env();
++      run_command("dynpart", 0);
++      run_command("bootd", 0);
++}
++
++
++static int seconds(void *user)
++{
++      return neo1973_new_second();
++}
++
++
++static int system_idle(void)
++{
++#ifdef  CONFIG_USBD_DFU
++      if (system_dfu_state)
++              return *system_dfu_state == DFU_STATE_appIDLE;
++#endif
++        return 1;
++}
++
++
++static void poweroff_if_idle(void *user)
++{
++      unsigned long flags;
++
++      local_irq_save(flags);
++      if (system_idle())
++              neo1973_poweroff();
++      local_irq_restore(flags);
++}
++
++
++static struct bootmenu_setup bootmenu_setup = {
++      .next_key = aux_key,
++      .enter_key = on_key,
++      .seconds = seconds,
++      .idle_action = poweroff_if_idle,
++};
++
++
++void neo1973_bootmenu(void)
++{
++      bootmenu_add("Boot", NULL, "bootd");
++      bootmenu_init(&bootmenu_setup);
++      bootmenu_add("Factory reset", factory_reset, NULL);
++      bootmenu();
++}
+Index: u-boot/board/neo1973/gta01/gta01.c
+===================================================================
+--- u-boot.orig/board/neo1973/gta01/gta01.c
++++ u-boot/board/neo1973/gta01/gta01.c
+@@ -229,10 +229,15 @@ int board_late_init(void)
+       extern unsigned char booted_from_nand;
+       unsigned char tmp;
+       char buf[32];
++      int menu_vote = 0; /* <= 0: no, > 0: yes */
++      int seconds = 0;
+       /* Initialize the Power Management Unit with a safe register set */
+       pcf50606_init();
++      /* if there's no other reason, must be regular reset */
++      neo1973_wakeup_cause = NEO1973_WAKEUP_RESET;
++
+       if (!booted_from_nand)
+               goto woken_by_reset;
+@@ -242,45 +247,41 @@ int board_late_init(void)
+       setenv("pcf50606_int1", buf);
+       if (tmp & PCF50606_INT1_ALARM) {
+-              /* we've been woken up by RTC alarm or charger insert, boot */
++              /* we've been woken up by RTC alarm, boot */
+               neo1973_wakeup_cause = NEO1973_WAKEUP_ALARM;
+               goto continue_boot;
+       }
+       if (tmp & PCF50606_INT1_EXTONR) {
++              /* we've been woken up by charger insert */
+               neo1973_wakeup_cause = NEO1973_WAKEUP_CHARGER;
+       }
+       if (tmp & PCF50606_INT1_ONKEYF) {
+-              int seconds = 0;
+-              neo1973_wakeup_cause = NEO1973_WAKEUP_POWER_KEY;
+               /* we've been woken up by a falling edge of the onkey */
++              neo1973_wakeup_cause = NEO1973_WAKEUP_POWER_KEY;
++      }
+-              /* we can't just setenv(bootdelay,-1) because that would
+-               * accidentially become permanent if the user does saveenv */
+-              if (neo1973_911_key_pressed())
+-                      nobootdelay = 1;
+-
+-              while (1) {
+-                      u_int8_t int1, oocs;
+-
+-                      oocs = pcf50606_reg_read(PCF50606_REG_OOCS);
+-                      if (oocs & PFC50606_OOCS_ONKEY)
+-                              break;
+-
+-                      int1 = pcf50606_reg_read(PCF50606_REG_INT1);
+-                      if (int1 & PCF50606_INT1_SECOND)
+-                              seconds++;
+-
+-                      if (seconds >= POWER_KEY_SECONDS)
+-                              goto continue_boot;
+-              }
+-              /* Power off if minimum number of seconds not reached */
+-              neo1973_poweroff();
++      if (neo1973_wakeup_cause == NEO1973_WAKEUP_CHARGER) {
++              /* if we still think it was only a charger insert, boot */
++              goto continue_boot;
+       }
+ woken_by_reset:
+-      /* if there's no other reason, must be regular reset */
+-      neo1973_wakeup_cause = NEO1973_WAKEUP_RESET;
++
++      while (neo1973_wakeup_cause == NEO1973_WAKEUP_RESET ||
++          neo1973_on_key_pressed()) {
++              if (neo1973_aux_key_pressed())
++                      menu_vote++;
++              else
++                      menu_vote--;
++
++              if (neo1973_new_second())
++                      seconds++;
++              if (seconds >= POWER_KEY_SECONDS)
++                      goto continue_boot;
++      }
++      /* Power off if minimum number of seconds not reached */
++      neo1973_poweroff();
+ continue_boot:
+       jbt6k74_init();
+@@ -304,6 +305,11 @@ continue_boot:
+       }
+ #endif
++      if (menu_vote > 0) {
++              neo1973_bootmenu();
++              nobootdelay = 1;
++      }
++
+       return 0;
+ }
+@@ -369,7 +375,17 @@ void neo1973_vibrator(int on)
+ #endif
+ }
+-int neo1973_911_key_pressed(void)
++int neo1973_new_second(void)
++{
++      return pcf50606_reg_read(PCF50606_REG_INT1) & PCF50606_INT1_SECOND;
++}
++
++int neo1973_on_key_pressed(void)
++{
++      return !(pcf50606_reg_read(PCF50606_REG_OOCS) & PFC50606_OOCS_ONKEY);
++}
++
++int neo1973_aux_key_pressed(void)
+ {
+       S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+       if (gpio->GPFDAT & (1 << 6))
+Index: u-boot/board/neo1973/gta01/Makefile
+===================================================================
+--- u-boot.orig/board/neo1973/gta01/Makefile
++++ u-boot/board/neo1973/gta01/Makefile
+@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
+ LIB   = lib$(BOARD).a
+-OBJS  := gta01.o pcf50606.o ../common/cmd_neo1973.o ../common/jbt6k74.o ../common/udc.o
++OBJS  := gta01.o pcf50606.o ../common/cmd_neo1973.o ../common/jbt6k74.o ../common/udc.o ../common/bootmenu.o
+ SOBJS := ../common/lowlevel_init.o
+ .PHONY:       all
+Index: u-boot/board/neo1973/common/neo1973.h
+===================================================================
+--- u-boot.orig/board/neo1973/common/neo1973.h
++++ u-boot/board/neo1973/common/neo1973.h
+@@ -29,4 +29,10 @@ int neo1973_911_key_pressed(void);
+ const char *neo1973_get_charge_status(void);
+ int neo1973_set_charge_mode(enum neo1973_charger_cmd cmd);
++int neo1973_new_second(void);
++int neo1973_on_key_pressed(void);
++int neo1973_aux_key_pressed(void);
++
++void neo1973_bootmenu(void);
++
+ #endif
+Index: u-boot/common/console.c
+===================================================================
+--- u-boot.orig/common/console.c
++++ u-boot/common/console.c
+@@ -160,8 +160,12 @@ void fprintf (int file, const char *fmt,
+ /** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/
++void (*console_poll_hook)(int activity);
++
+ int getc (void)
+ {
++      while (console_poll_hook && !tstc());
++
+       if (gd->flags & GD_FLG_DEVINIT) {
+               /* Get from the standard input */
+               return fgetc (stdin);
+@@ -171,7 +175,7 @@ int getc (void)
+       return serial_getc ();
+ }
+-int tstc (void)
++static int do_tstc (void)
+ {
+       if (gd->flags & GD_FLG_DEVINIT) {
+               /* Test the standard input */
+@@ -182,6 +186,16 @@ int tstc (void)
+       return serial_tstc ();
+ }
++int tstc (void)
++{
++      int ret;
++
++      ret = do_tstc();
++      if (console_poll_hook)
++              console_poll_hook(ret);
++      return ret;
++}
++
+ void putc (const char c)
+ {
+ #ifdef CONFIG_SILENT_CONSOLE
+Index: u-boot/include/console.h
+===================================================================
+--- u-boot.orig/include/console.h
++++ u-boot/include/console.h
+@@ -33,6 +33,8 @@
+ extern device_t       *stdio_devices[] ;
+ extern char *stdio_names[MAX_FILES] ;
++extern void (*console_poll_hook)(int activity);
++
+ int console_realloc(int top);
+ #endif
+Index: u-boot/common/Makefile
+===================================================================
+--- u-boot.orig/common/Makefile
++++ u-boot/common/Makefile
+@@ -50,7 +50,8 @@ COBJS        = main.o ACEX1K.o altera.o bedbug.
+         memsize.o miiphybb.o miiphyutil.o \
+         s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \
+         usb.o usb_kbd.o usb_storage.o \
+-        virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o cmd_mfsl.o
++        virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o cmd_mfsl.o \
++        bootmenu.o
+ SRCS  := $(AOBJS:.o=.S) $(COBJS:.o=.c)
+ OBJS  := $(addprefix $(obj),$(AOBJS) $(COBJS))
+Index: u-boot/common/bootmenu.c
+===================================================================
+--- /dev/null
++++ u-boot/common/bootmenu.c
+@@ -0,0 +1,311 @@
++/*
++ * bootmenu.c - Boot menu
++ *
++ * Copyright (C) 2006-2007 by OpenMoko, Inc.
++ * Written by Werner Almesberger <werner@openmoko.org>
++ * All Rights Reserved
++ *
++ * 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.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
++ */
++
++
++#include <common.h>
++
++#ifdef CFG_BOOTMENU
++
++#include <malloc.h>
++#include <devices.h>
++#include <console.h>
++#include <bootmenu.h>
++
++
++extern const char version_string[];
++
++
++#define ANSI_CLEAR    "\e[2J"
++#define ANSI_REVERSE  "\e[7m"
++#define       ANSI_NORMAL     "\e[m"
++#define ANSI_GOTOYX   "\e[%d;%dH"
++
++/*
++ * MIN_BOOT_MENU_TIMEOUT ensures that users can't by accident set the timeout
++ * unusably short.
++ */
++#define MIN_BOOT_MENU_TIMEOUT 10      /* 10 seconds */
++#define BOOT_MENU_TIMEOUT     60      /* 60 seconds */
++#define AFTER_COMMAND_WAIT    3       /* wait (2,3] after running commands */
++#define       MAX_MENU_ITEMS          10      /* cut off after that many */
++
++#define       TOP_ROW         2
++#define       MENU_0_ROW      (TOP_ROW+5)
++
++
++struct option {
++      const char *label;
++      void (*fn)(void *user); /* run_command if NULL */
++      void *user;
++};
++
++
++static const struct bootmenu_setup *setup;
++static struct option options[MAX_MENU_ITEMS];
++static int num_options = 0;
++static int max_width = 0;
++
++static device_t *bm_con;
++
++
++static void bm_printf(const char *fmt, ...)
++{
++      va_list args;
++      char printbuffer[CFG_PBSIZE];
++
++      va_start(args, fmt);
++      vsprintf(printbuffer, fmt, args);
++      va_end(args);
++
++      bm_con->puts(printbuffer);
++}
++
++
++static char *get_option(int n)
++{
++      char name[] = "menu_XX";
++
++      sprintf(name+5, "%d", n);
++      return getenv(name);
++}
++
++
++static void print_option(const struct option *option, int reverse)
++{
++      int n = option-options;
++
++      bm_printf(ANSI_GOTOYX, MENU_0_ROW+n, 1);
++      if (reverse)
++              bm_printf(ANSI_REVERSE);
++      bm_printf("  %-*s  ", max_width, option->label);
++      if (reverse)
++              bm_printf(ANSI_NORMAL);
++}
++
++
++static int get_var_positive_int(char *var, int default_value)
++{
++      const char *s;
++      char *end;
++      int n;
++
++      s = getenv(var);
++      if (!s)
++              return default_value;
++        n = simple_strtoul(s, &end, 0);
++      if (!*s || *end || n < 1)
++              return default_value;
++      return n;
++}
++
++
++static void show_bootmenu(void)
++{
++      const struct option *option;
++
++      bm_printf(ANSI_CLEAR ANSI_GOTOYX "%s", TOP_ROW, 1, version_string);
++      bm_printf(ANSI_GOTOYX "*** BOOT MENU ***", TOP_ROW+3, 1);
++      bm_printf(ANSI_GOTOYX, MENU_0_ROW, 1);
++
++      for (option = options; option != options+num_options; option++)
++              print_option(option, option == options);
++
++      bm_printf("\n\nPress [AUX] to select, [POWER] to execute.\n");
++}
++
++
++static void redirect_console(int grab)
++{
++      static device_t *orig_stdout, *orig_stderr;
++
++      if (grab) {
++              orig_stdout = stdio_devices[stdout];
++              orig_stderr = stdio_devices[stderr];
++              stdio_devices[stdout] = bm_con;
++              stdio_devices[stderr] = bm_con;
++      }
++      else {
++              /*
++               * Make this conditional, because the command may also change
++               * the console.
++               */
++              if (stdio_devices[stdout] == bm_con)
++                      stdio_devices[stdout] = orig_stdout;
++              if (stdio_devices[stderr] == bm_con)
++                      stdio_devices[stderr] = orig_stderr;
++      }
++}
++
++
++static void do_option(const struct option *option)
++{
++      int seconds, aux;
++
++      bm_printf(ANSI_CLEAR ANSI_GOTOYX, 1, 1);
++      redirect_console(1);
++
++      if (option->fn)
++              option->fn(option->user);
++      else
++              run_command(option->user, 0);
++
++      redirect_console(0);
++      seconds = get_var_positive_int("after_command_wait",
++          AFTER_COMMAND_WAIT);
++      if (seconds)
++              bm_printf("\nPress [AUX] to %s.",
++                  option ? "return to boot menu" : "power off");
++      aux = 1; /* require up-down transition */
++      while (seconds) {
++              int tmp;
++
++              tmp = setup->next_key(setup->user);
++              if (tmp && !aux)
++                      break;
++              aux = tmp;
++              if (setup->seconds(setup->user))
++                      seconds--;
++      }
++      if (!option)
++              setup->idle_action(setup->idle_action);
++      show_bootmenu();
++}
++
++
++static void bootmenu_hook(int activity)
++{
++      static int aux = 1, on = 1;
++      static const struct option *option = options;
++      static int seconds = 0;
++      int tmp;
++
++      if (activity)
++              seconds = 0;
++      tmp = setup->next_key(setup->user);
++      if (tmp && !aux) {
++              print_option(option, 0);
++              option++;
++              if (option == options+num_options)
++                      option = options;
++              print_option(option, 1);
++              seconds = 0;
++      }
++      aux = tmp;
++      tmp = setup->enter_key(setup->user);
++      if (tmp && !on) {
++              do_option(option);
++              option = options;
++              seconds = 0;
++      }
++      on = tmp;
++      if (setup->seconds(setup->user)) {
++              int timeout;
++
++              timeout = get_var_positive_int("boot_menu_timeout",
++                  BOOT_MENU_TIMEOUT);
++              if (timeout < MIN_BOOT_MENU_TIMEOUT)
++                      timeout = MIN_BOOT_MENU_TIMEOUT;
++              if (++seconds > timeout) {
++                      setup->idle_action(setup->idle_action);
++                      seconds = 0;
++              }
++      }
++}
++
++
++static device_t *find_console(const char *name)
++{
++      int i;
++
++      for (i = 1; i != ListNumItems(devlist); i++) {
++              device_t *dev = ListGetPtrToItem(devlist, i);
++
++              if (!strcmp(name, dev->name))
++                      if (dev->flags & DEV_FLAGS_OUTPUT)
++                              return dev;
++      }
++      return NULL;
++}
++
++
++void bootmenu_add(const char *label, void (*fn)(void *user), void *user)
++{
++      int len;
++
++      options[num_options].label = label;
++      options[num_options].fn = fn;
++      options[num_options].user = user;
++      num_options++;
++
++      len = strlen(label);
++      if (len > max_width)
++              max_width = len;
++}
++
++
++void bootmenu_init(struct bootmenu_setup *__setup)
++{
++      int n;
++
++      setup = __setup;
++      for (n = 1; n != MAX_MENU_ITEMS+1; n++) {
++              const char *spec, *colon;
++
++              spec = get_option(n);
++              if (!spec)
++                      continue;
++              colon = strchr(spec, ':');
++              if (!colon)
++                      bootmenu_add(spec, NULL, (char *) spec);
++              else {
++                      char *label;
++                      int len = colon-spec;
++
++                      label = malloc(len+1);
++                      if (!label)
++                              return;
++                      memcpy(label, spec, len);
++                      label[len] = 0;
++                      bootmenu_add(label, NULL, (char *) colon+1);
++              }
++      }
++}
++
++
++void bootmenu(void)
++{
++      bm_con = find_console("vga");
++      if (bm_con && bm_con->start && bm_con->start() < 0)
++              bm_con = NULL;
++      if (!bm_con)
++              bm_con = stdio_devices[stdout];
++      if (!bm_con)
++              return;
++#if 0
++      console_assign(stdout, "vga");
++      console_assign(stderr, "vga");
++#endif
++      show_bootmenu();
++      console_poll_hook = bootmenu_hook;
++}
++
++#endif /* CFG_BOOTMENU */
+Index: u-boot/include/bootmenu.h
+===================================================================
+--- /dev/null
++++ u-boot/include/bootmenu.h
+@@ -0,0 +1,71 @@
++/*
++ * bootmenu.h - Boot menu
++ *
++ * Copyright (C) 2006-2007 by OpenMoko, Inc.
++ * Written by Werner Almesberger <werner@openmoko.org>
++ * All Rights Reserved
++ *
++ * 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.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
++ */
++
++#ifndef BOOTMENU_H
++#define BOOTMENU_H
++
++#define MIN_BOOT_MENU_TIMEOUT 10      /* 10 seconds */
++#define BOOT_MENU_TIMEOUT     60      /* 60 seconds */
++#define AFTER_COMMAND_WAIT    3       /* wait (2,3] after running commands */
++#define MAX_MENU_ITEMS                10      /* cut off after that many */
++
++
++struct bootmenu_setup {
++      /* non-zero while the "next" key is being pressed */
++      int (*next_key)(void *user);
++
++      /* non-zero while the "enter" key is being pressed */
++      int (*enter_key)(void *user);
++
++      /* return the number of seconds that have passed since the last call
++         to "seconds". It's okay to limit the range to [0, 1]. */
++      int (*seconds)(void *user);
++
++      /* action to take if the boot menu times out */
++      void (*idle_action)(void *user);
++
++      /* user-specific data, passes "as is" to the functions above */
++      void *user;
++};
++
++
++/*
++ * Initialize the menu from the environment.
++ */
++
++void bootmenu_init(struct bootmenu_setup *setup);
++
++/*
++ * To add entries on top of the boot menu, call bootmenu_add before
++ * bootmenu_init. To add entries at the end, call it after bootmenu_init.
++ * If "fn" is NULL, the command specified in "user" is executed.
++ */
++
++void bootmenu_add(const char *label, void (*fn)(void *user), void *user);
++
++/*
++ * Run the boot menu.
++ */
++
++void bootmenu(void);
++
++#endif /* !BOOTMENU_H */
+Index: u-boot/include/configs/neo1973_gta01.h
+===================================================================
+--- u-boot.orig/include/configs/neo1973_gta01.h
++++ u-boot/include/configs/neo1973_gta01.h
+@@ -160,6 +160,8 @@
+ /* valid baudrates */
+ #define CFG_BAUDRATE_TABLE    { 9600, 19200, 38400, 57600, 115200 }
++#define CFG_BOOTMENU
++
+ /*-----------------------------------------------------------------------
+  * Stack sizes
+  *
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/cmd-unzip.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/cmd-unzip.patch
new file mode 100644 (file)
index 0000000..ee4c198
--- /dev/null
@@ -0,0 +1,58 @@
+common/cmd_mem.c: new command "unzip srcaddr dstaddr [dstsize]" to unzip from
+  memory to memory, and option CONFIG_UNZIP to enable it
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/common/cmd_mem.c
+===================================================================
+--- u-boot.orig/common/cmd_mem.c
++++ u-boot/common/cmd_mem.c
+@@ -1148,6 +1148,34 @@ int do_mem_crc (cmd_tbl_t *cmdtp, int fl
+ }
+ #endif        /* CONFIG_CRC32_VERIFY */
++
++#ifdef CONFIG_UNZIP
++int  gunzip (void *, int, unsigned char *, unsigned long *);
++
++int do_unzip ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++      unsigned long src, dst;
++      unsigned long src_len = ~0UL, dst_len = ~0UL;
++      int err;
++
++      switch (argc) {
++              case 4:
++                      dst_len = simple_strtoul(argv[3], NULL, 16);
++                      /* fall through */
++              case 3:
++                      src = simple_strtoul(argv[1], NULL, 16);
++                      dst = simple_strtoul(argv[2], NULL, 16);
++                      break;
++              default:
++                      printf ("Usage:\n%s\n", cmdtp->usage);
++                      return 1;
++      }
++
++      return !!gunzip((void *) dst, dst_len, (void *) src, &src_len);
++}
++#endif /* CONFIG_UNZIP */
++
++
+ /**************************************************/
+ #if (CONFIG_COMMANDS & CFG_CMD_MEMORY)
+ U_BOOT_CMD(
+@@ -1251,5 +1279,13 @@ U_BOOT_CMD(
+ );
+ #endif /* CONFIG_MX_CYCLIC */
++#ifdef CONFIG_UNZIP
++U_BOOT_CMD(
++      unzip,  4,      1,      do_unzip,
++      "unzip - unzip a memory region\n",
++      "srcaddr dstaddr [dstsize]\n"
++);
++#endif /* CONFIG_UNZIP */
++
+ #endif
+ #endif        /* CFG_CMD_MEMORY */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/console-ansi.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/console-ansi.patch
new file mode 100644 (file)
index 0000000..2ac5b75
--- /dev/null
@@ -0,0 +1,127 @@
+drivers/cfb_console.c: added processing of ANSI escape sequences \e[2J, \e[m,
+  \e[7m, and \e[row;colH
+drivers/cfb_console.c (video_putc): make \r return to the beginning of the line
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/drivers/cfb_console.c
+===================================================================
+--- u-boot.orig/drivers/cfb_console.c
++++ u-boot/drivers/cfb_console.c
+@@ -181,6 +181,7 @@ CONFIG_VIDEO_HW_CURSOR:         - Uses the 
+ #include <version.h>
+ #include <linux/types.h>
++#include <linux/ctype.h>
+ #include <devices.h>
+ #include <video_font.h>
+ #ifdef CFG_CMD_DATE
+@@ -676,10 +677,96 @@ static void console_newline (void)
+ /*****************************************************************************/
++static enum {
++      CS_NORMAL = 0,
++      CS_ESC,
++      CS_NUM1,
++      CS_NUM2,
++} state = 0;
++
++static int num1, num2;
++
++
++static void swap_drawing_colors(void)
++{
++      eorx = fgx;
++      fgx = bgx;
++      bgx = eorx;
++      eorx = fgx ^ bgx;
++}
++
++
++static void process_sequence(char c)
++{
++      static int inverted = 0;
++      int i, inv;
++
++      switch (c) {
++              case 'J':
++                      /* assume num1 == 2 */
++                      for (i = 0; i != CONSOLE_ROWS; i++)
++                              console_scrollup();
++                      break;
++              case 'H':
++                      if (num1 > CONSOLE_ROWS || num2 > CONSOLE_COLS)
++                              break;
++                      console_col = num2 ? num2-1 : 0;
++                      console_row = num1 ? num1-1 : 0;
++                      break;
++              case 'm':
++                      inv = num1 == 7;
++                      if (num1 && !inv)
++                              break;
++                      if (inverted != inv)
++                              swap_drawing_colors();
++                      inverted = inv;
++                      break;
++      }
++}
++
++
++static void escape_sequence(char c)
++{
++      switch (state) {
++              case CS_ESC:
++                      state = c == '[' ? CS_NUM1 : CS_NORMAL;
++                      num1 = num2 = 0;
++                      break;
++              case CS_NUM1:
++                      if (isdigit(c))
++                              num1 = num1*10+c-'0';
++                      else if (c == ';')
++                              state = CS_NUM2;
++                      else {
++                              process_sequence(c);
++                              state = CS_NORMAL;
++                      }
++                      break;
++              case CS_NUM2:
++                      if (isdigit(c))
++                              num2 = num2*10+c-'0';
++                      else {
++                              process_sequence(c);
++                              state = CS_NORMAL;
++                      }
++              default:
++                      /* can't happen */;
++      }
++}
++
++
+ void video_putc (const char c)
+ {
++      if (state) {
++              escape_sequence(c);
++              CURSOR_SET;
++              return;
++      }
++
+       switch (c) {
+-      case 13:                /* ignore */
++      case 13:                /* return to beginning of line */
++              CURSOR_OFF;
++              console_col = 0;
+               break;
+       case '\n':              /* next line */
+@@ -698,6 +785,10 @@ void video_putc (const char c)
+               console_back ();
+               break;
++      case '\e':
++              state = CS_ESC;
++              break;
++
+       default:                /* draw the char */
+               video_putchar (console_col * VIDEO_FONT_WIDTH,
+                              console_row * VIDEO_FONT_HEIGHT,
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/default-env.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/default-env.patch
new file mode 100644 (file)
index 0000000..b9ae4f2
--- /dev/null
@@ -0,0 +1,101 @@
+common/env_common.c (default_env): new function that resets the environment to
+  the default value
+common/env_common.c (env_relocate): use default_env instead of own copy
+common/env_nand.c (env_relocate_spec): use default_env instead of own copy
+include/environment.h: added default_env prototype
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/common/env_common.c
+===================================================================
+--- u-boot.orig/common/env_common.c
++++ u-boot/common/env_common.c
+@@ -202,6 +202,25 @@ uchar *env_get_addr (int index)
+       }
+ }
++void default_env(void)
++{
++      if (sizeof(default_environment) > ENV_SIZE)
++      {
++              puts ("*** Error - default environment is too large\n\n");
++              return;
++      }
++
++      memset (env_ptr, 0, sizeof(env_t));
++      memcpy (env_ptr->data,
++              default_environment,
++              sizeof(default_environment));
++#ifdef CFG_REDUNDAND_ENVIRONMENT
++      env_ptr->flags = 0xFF;
++#endif
++      env_crc_update ();
++      gd->env_valid = 1;
++}
++
+ void env_relocate (void)
+ {
+       DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__,
+@@ -245,23 +264,8 @@ void env_relocate (void)
+               gd->env_valid = 0;
+ #endif
+-      if (gd->env_valid == 0) {
+-              if (sizeof(default_environment) > ENV_SIZE)
+-              {
+-                      puts ("*** Error - default environment is too large\n\n");
+-                      return;
+-              }
+-
+-              memset (env_ptr, 0, sizeof(env_t));
+-              memcpy (env_ptr->data,
+-                      default_environment,
+-                      sizeof(default_environment));
+-#ifdef CFG_REDUNDAND_ENVIRONMENT
+-              env_ptr->flags = 0xFF;
+-#endif
+-              env_crc_update ();
+-              gd->env_valid = 1;
+-      }
++      if (gd->env_valid == 0)
++              default_env();
+       else {
+               env_relocate_spec ();
+       }
+Index: u-boot/common/env_nand.c
+===================================================================
+--- u-boot.orig/common/env_nand.c
++++ u-boot/common/env_nand.c
+@@ -313,19 +313,7 @@ void env_relocate_spec (void)
+ static void use_default()
+ {
+       puts ("*** Warning - bad CRC or NAND, using default environment\n\n");
+-
+-      if (default_environment_size > CFG_ENV_SIZE){
+-              puts ("*** Error - default environment is too large\n\n");
+-              return;
+-      }
+-
+-      memset (env_ptr, 0, sizeof(env_t));
+-      memcpy (env_ptr->data,
+-                      default_environment,
+-                      default_environment_size);
+-      env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE);
+-      gd->env_valid = 1;
+-
++      default_env();
+ }
+ #endif
+Index: u-boot/include/environment.h
+===================================================================
+--- u-boot.orig/include/environment.h
++++ u-boot/include/environment.h
+@@ -107,4 +107,7 @@ typedef    struct environment_s {
+       unsigned char   data[ENV_SIZE]; /* Environment data             */
+ } env_t;
++
++void default_env(void);
++
+ #endif        /* _ENVIRONMENT_H_ */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/dontask.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/dontask.patch
new file mode 100644 (file)
index 0000000..23d4b13
--- /dev/null
@@ -0,0 +1,22 @@
+common/cmd_nand.c (yes): if the environment variable "dontask" is set to "y" or
+  "Y", non-interactively assume the answer was "yes". In all other cases, ask.
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/common/cmd_nand.c
+===================================================================
+--- u-boot.orig/common/cmd_nand.c
++++ u-boot/common/cmd_nand.c
+@@ -165,8 +165,12 @@ out:
+ static int yes(void)
+ {
++      char *s;
+       char c;
++      s = getenv("dontask");
++      if (s && (s[0] =='y' || s[0] == 'Y') && !s[1])
++              return 1;
+       c = getc();
+       if (c != 'y' && c != 'Y')
+               return 0;
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/dynenv-harden.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/dynenv-harden.patch
new file mode 100644 (file)
index 0000000..cf12352
--- /dev/null
@@ -0,0 +1,139 @@
+common/cmd_nand.c: globalized arg_off_size
+include/util.h: new header to convenience functions, such as arg_off_size
+common/cmd_dynenv.c (do_dynenv): use arg_off_size to sanity-check offset and to
+  allow use of partition name
+common/cmd_dynenv.c (do_dynenv): indicate in no uncertain terms when an update
+  would not work due to Flash bits already cleared
+common/cmd_dynenv.c (do_dynenv): update CFG_ENV_OFFSET after successful "dynenv
+  set", so that we can write the new environment without having to reboot
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/common/cmd_nand.c
+===================================================================
+--- u-boot.orig/common/cmd_nand.c
++++ u-boot/common/cmd_nand.c
+@@ -100,7 +100,7 @@ static inline int str2long(char *p, ulon
+       return (*p != '\0' && *endptr == '\0') ? 1 : 0;
+ }
+-static int
++int
+ arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size)
+ {
+       int idx = nand_curr_device;
+Index: u-boot/include/util.h
+===================================================================
+--- /dev/null
++++ u-boot/include/util.h
+@@ -0,0 +1,33 @@
++/*
++ * util.h - Convenience functions
++ *
++ * (C) Copyright 2006-2007 OpenMoko, Inc.
++ * Author: Werner Almesberger <werner@openmoko.org>
++ *
++ * 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 UTIL_H
++#define UTIL_H
++
++#include "nand.h"
++
++
++/* common/cmd_nand.c */
++int arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off,
++  ulong *size);
++
++#endif /* UTIL_H */
+Index: u-boot/common/cmd_dynenv.c
+===================================================================
+--- u-boot.orig/common/cmd_dynenv.c
++++ u-boot/common/cmd_dynenv.c
+@@ -23,6 +23,7 @@
+ #include <malloc.h>
+ #include <environment.h>
+ #include <nand.h>
++#include <util.h>
+ #include <asm/errno.h>
+ #if defined(CFG_ENV_OFFSET_OOB)
+@@ -39,8 +40,8 @@ int do_dynenv(cmd_tbl_t *cmdtp, int flag
+       if (!buf)
+               return -ENOMEM;
++      ret = mtd->read_oob(mtd, 8, size, (size_t *) &size, (u_char *) buf);
+       if (!strcmp(cmd, "get")) {
+-              ret = mtd->read_oob(mtd, 8, size, (size_t *) &size, (u_char *) buf);
+               if (buf[0] == 'E' && buf[1] == 'N' &&
+                   buf[2] == 'V' && buf[3] == '0')
+@@ -49,7 +50,8 @@ int do_dynenv(cmd_tbl_t *cmdtp, int flag
+                       printf("No dynamic environment marker in OOB block 0\n");
+       } else if (!strcmp(cmd, "set")) {
+-              unsigned long addr;
++              unsigned long addr, dummy;
++
+               if (argc < 3)
+                       goto usage;
+@@ -57,7 +59,23 @@ int do_dynenv(cmd_tbl_t *cmdtp, int flag
+               buf[1] = 'N';
+               buf[2] = 'V';
+               buf[3] = '0';
+-              addr = simple_strtoul(argv[2], NULL, 16);
++
++              if (arg_off_size(argc-2, argv+2, mtd, &addr, &dummy) < 0) {
++                      printf("Offset or partition name expected\n");
++                      goto fail;
++              }
++              if (!ret) {
++                      uint8_t tmp[4];
++                      int i;
++
++                      memcpy(&tmp, &addr, 4);
++                      for (i = 0; i != 4; i++)
++                              if (tmp[i] & ~buf[i+4]) {
++                                      printf("ERROR: erase OOB block to "
++                                        "write this value\n");
++                                      goto fail;
++                              }
++              }
+               memcpy(buf+4, &addr, 4);
+               printf("%02x %02x %02x %02x - %02x %02x %02x %02x\n",
+@@ -65,6 +83,8 @@ int do_dynenv(cmd_tbl_t *cmdtp, int flag
+                       buf[4], buf[5], buf[6], buf[7]);
+               ret = mtd->write_oob(mtd, 8, size, (size_t *) &size, (u_char *) buf);
++              if (!ret)
++                      CFG_ENV_OFFSET = addr;
+       } else
+               goto usage;
+@@ -72,8 +92,9 @@ int do_dynenv(cmd_tbl_t *cmdtp, int flag
+       return ret;
+ usage:
+-      free(buf);
+       printf("Usage:\n%s\n", cmdtp->usage);
++fail:
++      free(buf);
+       return 1;
+ }
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/early-powerdown.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/early-powerdown.patch
new file mode 100644 (file)
index 0000000..7326c2d
--- /dev/null
@@ -0,0 +1,40 @@
+Index: u-boot/board/neo1973/neo1973.c
+===================================================================
+--- u-boot.orig/board/neo1973/gta01/gta01.c
++++ u-boot/board/neo1973/gta01/gta01.c
+@@ -68,8 +68,12 @@ DECLARE_GLOBAL_DATA_PTR;
+ #define U_M_PDIV      0x2
+ #define U_M_SDIV      0x3
++#define VALID_WAKEUP_REASONS (PCF50606_INT1_ONKEYF | PCF50606_INT1_ALARM)
++
+ unsigned int neo1973_wakeup_cause;
+ extern int nobootdelay;
++static unsigned char int1;
++
+ static inline void delay (unsigned long loops)
+ {
+@@ -179,6 +183,13 @@ int board_init (void)
+ #error Please define GTA01 version
+ #endif
++      i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
++      int1 = pcf50606_reg_read(PCF50606_REG_INT1);
++      if (!(int1 & VALID_WAKEUP_REASONS) && !neo1973_aux_key_pressed()) {
++              pcf50606_reg_write(PCF50606_REG_OOCC1, PCF50606_OOCC1_GOSTDBY);
++              while (1);
++      }
++
+       /* arch number of SMDK2410-Board */
+       gd->bd->bi_arch_number = MACH_TYPE_NEO1973_GTA01;
+@@ -200,7 +211,7 @@ int board_late_init(void)
+       pcf50606_init();
+       /* obtain wake-up reason, save INT1 in environment */
+-      tmp = pcf50606_reg_read(PCF50606_REG_INT1);
++      tmp = int1; //pcf50606_reg_read(PCF50606_REG_INT1);
+       sprintf(buf, "0x%02x", tmp);
+       setenv("pcf50606_int1", buf);
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/enable-splash-bmp.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/enable-splash-bmp.patch
new file mode 100644 (file)
index 0000000..dcb721c
--- /dev/null
@@ -0,0 +1,56 @@
+drivers/cfb_console.c: include asm/byteorder.h for le32_to_cpu and friends
+  [ shouldn't someone else have found this long ago ? ]
+include/configs/neo1973.h (CONFIG_COMMANDS): add CFG_CMD_BMP
+include/configs/neo1973.h: enable splash screen and BMP support
+include/configs/neo1973.h: remove #if 1 ... #endif around video definitions
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/drivers/cfb_console.c
+===================================================================
+--- u-boot.orig/drivers/cfb_console.c
++++ u-boot/drivers/cfb_console.c
+@@ -191,6 +191,7 @@ CONFIG_VIDEO_HW_CURSOR:         - Uses the 
+ #if (CONFIG_COMMANDS & CFG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
+ #include <watchdog.h>
+ #include <bmp_layout.h>
++#include <asm/byteorder.h>
+ #endif /* (CONFIG_COMMANDS & CFG_CMD_BMP) || CONFIG_SPLASH_SCREEN */
+ /*****************************************************************************/
+Index: u-boot/include/configs/neo1973_gta01.h
+===================================================================
+--- u-boot.orig/include/configs/neo1973_gta01.h
++++ u-boot/include/configs/neo1973_gta01.h
+@@ -86,6 +86,7 @@
+                       /* CFG_CMD_IRQ   | */  \
+                       CFG_CMD_BOOTD    | \
+                       CFG_CMD_CONSOLE  | \
++                      CFG_CMD_BMP      | \
+                       CFG_CMD_ASKENV   | \
+                       CFG_CMD_RUN      | \
+                       CFG_CMD_ECHO     | \
+@@ -244,19 +245,21 @@
+ /* we have a board_late_init() function */
+ #define BOARD_LATE_INIT                       1
+-#if 1
+ #define CONFIG_VIDEO
+ #define CONFIG_VIDEO_S3C2410
+ #define CONFIG_CFB_CONSOLE
+ #define CONFIG_VIDEO_LOGO
++#define CONFIG_SPLASH_SCREEN
++#define CFG_VIDEO_LOGO_MAX_SIZE       (640*480+1024+100) /* 100 = slack */
++#define CONFIG_VIDEO_BMP_GZIP
+ #define CONFIG_VGA_AS_SINGLE_DEVICE
++#define CONFIG_UNZIP
+ #define VIDEO_KBD_INIT_FCT    0
+ #define VIDEO_TSTC_FCT                serial_tstc
+ #define VIDEO_GETC_FCT                serial_getc
+ #define LCD_VIDEO_ADDR                0x33d00000
+-#endif
+ #define CONFIG_S3C2410_NAND_BBT                1
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/env_nand_oob.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/env_nand_oob.patch
new file mode 100644 (file)
index 0000000..5a2dd61
--- /dev/null
@@ -0,0 +1,198 @@
+This patch adds support for CFG_ENV_OFFSET_PATCHED and 
+CFG_ENV_OFFSET_OOB.
+
+Both try to solve the problem of fixing the environment location in NAND flash
+at compile time, which doesn't work well if the NAND flash has a bad block at
+exactly that location.
+
+CFG_ENV_OFFSET_PATCHED puts the environment in a global variable.  You can then
+use the linker script to put that variable to a fixed location in the u-boot
+image.  Then you can use bianry patching during the production flash process.
+
+The idea of CFG_ENV_OFFSET_OOB is to store the environment offset in the NAND
+OOB data of block 0.  We can do this in case the vendor makes a guarantee that
+block 0 never is a factory-default bad block. 
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+
+Index: u-boot/common/env_nand.c
+===================================================================
+--- u-boot.orig/common/env_nand.c
++++ u-boot/common/env_nand.c
+@@ -271,6 +271,33 @@
+       ulong total;
+       int ret;
++#if defined(CFG_ENV_OFFSET_OOB)
++      struct mtd_info *mtd = &nand_info[0];
++      struct nand_chip *this = mtd->priv;
++      int buf_len;
++      uint8_t *buf;
++
++      buf_len = (1 << this->bbt_erase_shift);
++      buf_len += (buf_len >> this->page_shift) * mtd->oobsize;
++      buf = malloc(buf_len);
++      if (!buf)
++              return;
++
++      nand_read_raw(mtd, buf, 0, mtd->oobblock, mtd->oobsize);
++      if (buf[mtd->oobblock + 8 + 0] == 'E' &&
++          buf[mtd->oobblock + 8 + 1] == 'N' &&
++          buf[mtd->oobblock + 8 + 2] == 'V' &&
++          buf[mtd->oobblock + 8 + 3] == '0') {
++              CFG_ENV_OFFSET = *((unsigned long *) &buf[mtd->oobblock + 8 + 4]);
++              /* fall through to the normal environment reading code below */
++              free(buf);
++              puts("Found Environment offset in OOB..\n");
++      } else {
++              free(buf);
++              return use_default();
++      }
++#endif
++
+       total = CFG_ENV_SIZE;
+       ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
+       if (ret || total != CFG_ENV_SIZE)
+Index: u-boot/common/environment.c
+===================================================================
+--- u-boot.orig/common/environment.c
++++ u-boot/common/environment.c
+@@ -29,6 +29,12 @@
+ #undef        __ASSEMBLY__
+ #include <environment.h>
++#if defined(CFG_ENV_OFFSET_PATCHED)
++unsigned long env_offset = CFG_ENV_OFFSET_PATCHED;
++#elif defined(CFG_ENV_OFFSET_OOB)
++unsigned long env_offset = CFG_ENV_OFFSET_OOB;
++#endif
++
+ /*
+  * Handle HOSTS that have prepended
+  * crap on symbol names, not TARGETS.
+Index: u-boot/include/environment.h
+===================================================================
+--- u-boot.orig/include/environment.h
++++ u-boot/include/environment.h
+@@ -70,6 +70,10 @@
+ #endif        /* CFG_ENV_IS_IN_FLASH */
+ #if defined(CFG_ENV_IS_IN_NAND)
++#if defined(CFG_ENV_OFFSET_PATCHED) || defined(CFG_ENV_OFFSET_OOB)
++extern unsigned long env_offset;
++#define CFG_ENV_OFFSET env_offset
++#else
+ # ifndef CFG_ENV_OFFSET
+ #  error "Need to define CFG_ENV_OFFSET when using CFG_ENV_IS_IN_NAND"
+ # endif
+@@ -82,6 +86,7 @@
+ # ifdef CFG_ENV_IS_EMBEDDED
+ #  define ENV_IS_EMBEDDED     1
+ # endif
++#endif /* CFG_ENV_NAND_PATCHED */
+ #endif /* CFG_ENV_IS_IN_NAND */
+Index: u-boot/common/Makefile
+===================================================================
+--- u-boot.orig/common/Makefile
++++ u-boot/common/Makefile
+@@ -31,7 +31,7 @@
+         cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o \
+         cmd_cache.o cmd_console.o \
+         cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o \
+-        cmd_eeprom.o cmd_elf.o cmd_ext2.o \
++        cmd_dynenv.o cmd_eeprom.o cmd_elf.o cmd_ext2.o \
+         cmd_fat.o cmd_fdc.o cmd_fdt.o cmd_fdos.o cmd_flash.o cmd_fpga.o \
+         cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \
+         cmd_load.o cmd_log.o \
+Index: u-boot/common/cmd_dynenv.c
+===================================================================
+--- /dev/null
++++ u-boot/common/cmd_dynenv.c
+@@ -0,0 +1,85 @@
++/*
++ * (C) Copyright 2006-2007 OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * 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 <command.h>
++#include <malloc.h>
++#include <environment.h>
++#include <nand.h>
++#include <asm/errno.h>
++
++#if defined(CFG_ENV_OFFSET_OOB)
++
++int do_dynenv(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++      struct mtd_info *mtd = &nand_info[0];
++      int ret, size = 8;
++      uint8_t *buf;
++
++      char *cmd = argv[1];
++
++      buf = malloc(mtd->oobsize);
++      if (!buf)
++              return -ENOMEM;
++
++      if (!strcmp(cmd, "get")) {
++              ret = mtd->read_oob(mtd, 8, size, (size_t *) &size, (u_char *) buf);
++
++              if (buf[0] == 'E' && buf[1] == 'N' &&
++                  buf[2] == 'V' && buf[3] == '0')
++                      printf("0x%08x\n", *((u_int32_t *) &buf[4]));
++              else
++                      printf("No dynamic environment marker in OOB block 0\n");
++
++      } else if (!strcmp(cmd, "set")) {
++              unsigned long addr;
++              if (argc < 3)
++                      goto usage;
++
++              buf[0] = 'E';
++              buf[1] = 'N';
++              buf[2] = 'V';
++              buf[3] = '0';
++              addr = simple_strtoul(argv[2], NULL, 16);
++              memcpy(buf+4, &addr, 4);
++
++              printf("%02x %02x %02x %02x - %02x %02x %02x %02x\n",
++                      buf[0], buf[1], buf[2], buf[3],
++                      buf[4], buf[5], buf[6], buf[7]);
++
++              ret = mtd->write_oob(mtd, 8, size, (size_t *) &size, (u_char *) buf);
++      } else
++              goto usage;
++
++      free(buf);
++      return ret;
++
++usage:
++      free(buf);
++      printf("Usage:\n%s\n", cmdtp->usage);
++      return 1;
++}
++
++U_BOOT_CMD(dynenv, 3, 1, do_dynenv,
++      "dynenv  - dynamically placed (NAND) environment\n",
++      "dynenv set off - set enviromnent offset\n"
++      "dynenv get     - get environment offset\n");
++
++#endif /* CFG_ENV_OFFSET_OOB */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/ext2load_hex.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/ext2load_hex.patch
new file mode 100644 (file)
index 0000000..ff8e9cd
--- /dev/null
@@ -0,0 +1,17 @@
+This patch adds the hex-printing of the file size read by 'ext2load'
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+
+Index: u-boot.git/common/cmd_ext2.c
+===================================================================
+--- u-boot.git.orig/common/cmd_ext2.c  2007-01-02 18:26:17.000000000 +0100
++++ u-boot.git/common/cmd_ext2.c       2007-01-02 18:26:27.000000000 +0100
+@@ -279,7 +279,7 @@
+       /* Loading ok, update default load address */
+       load_addr = addr;
+-      printf ("\n%ld bytes read\n", filelen);
++      printf ("\n%ld (0x%lx) bytes read\n", filelen, filelen);
+       sprintf(buf, "%lX", filelen);
+       setenv("filesize", buf);
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/lowlevel_foo.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/lowlevel_foo.patch
new file mode 100644 (file)
index 0000000..715c46e
--- /dev/null
@@ -0,0 +1,229 @@
+board/neo1973/lowlevel_foo.S: http://people.openmoko.org/laforge/tmp/bbt-20070206/lowlevel_foo.S
+board/neo1973/lowlevel_foo.lds: http://people.openmoko.org/laforge/tmp/bbt-20070206/lowlevel_foo.lds
+board/neo1973/Makefile: added building of lowlevel_foo.bin (based on
+  http://people.openmoko.org/laforge/tmp/bbt-20070206/lowlevel_foo.build.sh)
+
+Index: u-boot/board/neo1973/common/lowlevel_foo.S
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/common/lowlevel_foo.S
+@@ -0,0 +1,82 @@
++
++_start:
++      b       reset
++undefvec:
++      b       undefvec
++swivec:
++      b       swivec
++pabtvec:
++      b       pabtvec
++dabtvec:
++      b       dabtvec
++rsvdvec:
++      b       rsvdvec
++irqvec:
++      b       irqvec
++fiqvec:
++      b       fiqvec
++
++reset:
++      /*
++       * set the cpu to SVC32 mode
++       */
++      mrs     r0,cpsr
++      bic     r0,r0,#0x1f
++      orr     r0,r0,#0xd3
++      msr     cpsr,r0
++
++/* turn off the watchdog */
++#define pWTCON                0x53000000
++#define INTMSK                0x4A000008      /* Interupt-Controller base addresses */
++#define INTSUBMSK     0x4A00001C
++#define CLKDIVN       0x4C000014      /* clock divisor register */
++
++      ldr     r0, =pWTCON
++      mov     r1, #0x0
++      str     r1, [r0]
++
++      mov     r1, #0xffffffff
++      ldr     r0, =INTMSK
++      str     r1, [r0]
++      ldr     r1, =0x3ff
++      ldr     r0, =INTSUBMSK
++      str     r1, [r0]
++
++      /* FCLK:HCLK:PCLK = 1:2:4 */
++      /* default FCLK is 120 MHz ! */
++      ldr     r0, =CLKDIVN
++      mov     r1, #3
++      str     r1, [r0]
++
++      bl      cpu_init_crit
++      ldr     r0,=TEXT_BASE
++      mov     pc, r0
++
++cpu_init_crit:
++      /*
++       * flush v4 I/D caches
++       */
++      mov     r0, #0
++      mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
++      mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
++
++      /*
++       * 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
++
++      /*
++       * before relocating, we have to setup RAM timing
++       * because memory timing is board-dependend, you will
++       * find a lowlevel_init.S in your board directory.
++       */
++      mov     ip, lr
++      bl      lowlevel_init
++      mov     lr, ip
++      mov     pc, lr
++
+Index: u-boot/board/neo1973/common/lowlevel_foo.lds
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/common/lowlevel_foo.lds
+@@ -0,0 +1,56 @@
++/*
++ * (C) Copyright 2002
++ * Gary Jennejohn, DENX Software Engineering, <gj@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      :
++      {
++        lowlevel_foo.o (.text)
++        *(.text)
++      }
++
++      . = ALIGN(4);
++      .rodata : { *(.rodata) }
++
++      . = ALIGN(4);
++      .data : { *(.data) }
++
++      . = ALIGN(4);
++      .got : { *(.got) }
++
++      . = .;
++      __u_boot_cmd_start = .;
++      .u_boot_cmd : { *(.u_boot_cmd) }
++      __u_boot_cmd_end = .;
++
++      . = ALIGN(4);
++      __bss_start = .;
++      .bss : { *(.bss) }
++      _end = .;
++}
+Index: u-boot/board/neo1973/gta01/Makefile
+===================================================================
+--- u-boot.orig/board/neo1973/gta01/Makefile
++++ u-boot/board/neo1973/gta01/Makefile
+@@ -28,14 +28,31 @@
+ OBJS  := gta01.o pcf50606.o ../common/cmd_neo1973.o ../common/jbt6k74.o ../common/udc.o
+ SOBJS := ../common/lowlevel_init.o
++.PHONY:       all
++
++all:  $(LIB) lowevel_foo.bin
++
+ $(LIB):       $(OBJS) $(SOBJS)
+       $(AR) crv $@ $(OBJS) $(SOBJS)
++lowlevel_foo.o:       ../common/lowlevel_foo.S
++      $(CC) -c -DTEXT_BASE=0x33F80000 -march=armv4 \
++        -o lowlevel_foo.o ../common/lowlevel_foo.S
++
++lowlevel_foo: lowlevel_foo.o ../common/lowlevel_init.o ../common/lowlevel_foo.lds
++      $(LD) -T ../common/lowlevel_foo.lds -Ttext 0x33f80000 -Bstatic \
++        ../common/lowlevel_init.o lowlevel_foo.o -o lowlevel_foo
++
++lowevel_foo.bin:      lowlevel_foo
++      $(CROSS_COMPILE)objcopy --gap-fill=0xff -O binary \
++        lowlevel_foo lowlevel_foo.bin
++
++
+ clean:
+-      rm -f $(SOBJS) $(OBJS)
++      rm -f $(SOBJS) $(OBJS) lowlevel_foo lowlevel_foo.o
+ distclean:    clean
+-      rm -f $(LIB) core *.bak .depend
++      rm -f $(LIB) core *.bak .depend lowlevel_foo.bin
+ #########################################################################
+Index: u-boot/board/qt2410/Makefile
+===================================================================
+--- u-boot.orig/board/qt2410/Makefile
++++ u-boot/board/qt2410/Makefile
+@@ -28,14 +28,31 @@
+ OBJS  := qt2410.o flash.o
+ SOBJS := lowlevel_init.o
++.PHONY:       all
++
++all:  $(LIB) lowevel_foo.bin
++
+ $(LIB):       $(OBJS) $(SOBJS)
+       $(AR) crv $@ $(OBJS) $(SOBJS)
++lowlevel_foo.o:       ../neo1973/common/lowlevel_foo.S
++      $(CC) -c -DTEXT_BASE=0x33F80000 -march=armv4 \
++        -o lowlevel_foo.o ../neo1973/common/lowlevel_foo.S
++
++lowlevel_foo: lowlevel_foo.o lowlevel_init.o \
++              ../neo1973/common/lowlevel_foo.lds
++      $(LD) -T ../neo1973/common/lowlevel_foo.lds -Ttext 0x33f80000 -Bstatic \
++          lowlevel_init.o lowlevel_foo.o -o lowlevel_foo
++
++lowevel_foo.bin:      lowlevel_foo
++      $(CROSS_COMPILE)objcopy --gap-fill=0xff -O binary \
++        lowlevel_foo lowlevel_foo.bin
++
+ clean:
+-      rm -f $(SOBJS) $(OBJS)
++      rm -f $(SOBJS) $(OBJS) lowlevel_foo lowlevel_foo.o
+ distclean:    clean
+-      rm -f $(LIB) core *.bak .depend
++      rm -f $(LIB) core *.bak .depend lowlevel_foo.bin
+ #########################################################################
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/makefile-no-dirafter.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/makefile-no-dirafter.patch
new file mode 100644 (file)
index 0000000..2ed26c3
--- /dev/null
@@ -0,0 +1,17 @@
+Index: git/tools/Makefile
+===================================================================
+--- git.orig/tools/Makefile    2007-10-03 16:51:38.000000000 +0100
++++ git/tools/Makefile 2007-10-03 16:52:03.000000000 +0100
+@@ -114,9 +114,9 @@
+ #
+ # Use native tools and options
+ #
+-CPPFLAGS   = -idirafter $(SRCTREE)/include \
+-              -idirafter $(OBJTREE)/include2 \
+-              -idirafter $(OBJTREE)/include \
++CPPFLAGS   = -I$(SRCTREE)/include \
++              -I$(OBJTREE)/include2 \
++              -I$(OBJTREE)/include \
+               -DTEXT_BASE=$(TEXT_BASE) -DUSE_HOSTCC
+ CFLAGS     = $(HOST_CFLAGS) $(CPPFLAGS) -O
+ AFLAGS           = -D__ASSEMBLY__ $(CPPFLAGS)
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/mmcinit-power-up.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/mmcinit-power-up.patch
new file mode 100644 (file)
index 0000000..fcf54b9
--- /dev/null
@@ -0,0 +1,73 @@
+board/neo1973/neo1973.c (board_late_init): moved MMC power-up to separate
+  function
+cpu/arm920t/s3c24x0/mmc.c (mmc_init): call mmc_power_up and return -ENODEV
+  immediately if there is no card
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/board/neo1973/neo1973.c
+===================================================================
+--- u-boot.orig/board/neo1973/neo1973.c
++++ u-boot/board/neo1973/neo1973.c
+@@ -223,6 +223,19 @@ int board_init (void)
+       return 0;
+ }
++int mmc_power_up(void)
++{
++#if defined(CONFIG_ARCH_GTA01B_v4)
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++      /* check if sd card is inserted, and power-up if it is */
++      if (gpio->GPFDAT & (1 << 5))
++              return 0;
++      gpio->GPBDAT &= ~(1 << 2);
++#endif /* !CONFIG_ARCH_GTA01B_v4 */
++      return 1;
++}
++
+ int board_late_init(void)
+ {
+       unsigned char tmp;
+@@ -289,14 +302,8 @@ continue_boot:
+       /* switch on the backlight */
+       neo1973_backlight(1);
+-#if defined(CONFIG_ARCH_GTA01B_v4)
+-      {
+-              /* check if sd card is inserted, and power-up if it is */
+-              S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+-              if (!(gpio->GPFDAT & (1 << 5)))
+-                      gpio->GPBDAT &= ~(1 << 2);
+-      }
+-#endif
++      /* check if sd card is inserted, and power-up if it is */
++      mmc_power_up();
+       return 0;
+ }
+Index: u-boot/cpu/arm920t/s3c24x0/mmc.c
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/mmc.c
++++ u-boot/cpu/arm920t/s3c24x0/mmc.c
+@@ -381,6 +381,11 @@ static void print_sd_cid(const struct sd
+           cid->crc >> 1, cid->crc & 1);
+ }
++int __attribute__((weak)) mmc_power_up(void)
++{
++      return 1;
++}
++
+ int mmc_init(int verbose)
+ {
+       int retries, rc = -ENODEV;
+@@ -393,6 +398,8 @@ int mmc_init(int verbose)
+       debug("mmc_init(PCLK=%u)\n", get_PCLK());
+       clk_power->CLKCON |= (1 << 9);
++      if (!mmc_power_up())
++              return -ENODEV;
+       /* S3C2410 has some bug that prevents reliable operation at higher speed */
+       //sdi->SDIPRE = 0x3e;  /* SDCLK = PCLK/2 / (SDIPRE+1) = 396kHz */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-badisbad.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-badisbad.patch
new file mode 100644 (file)
index 0000000..a5800e2
--- /dev/null
@@ -0,0 +1,30 @@
+This patch makes nand_block_checkbad check both the BBT and the actual
+OOB data. This avoids accidently passing blocks as good when BBT and
+OOB markers are not synchronized, e.g., before "nand createbbt".
+
+Experimental.
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/drivers/nand/nand_base.c
+===================================================================
+--- u-boot.orig/drivers/nand/nand_base.c
++++ u-boot/drivers/nand/nand_base.c
+@@ -517,11 +517,14 @@ static int nand_block_checkbad (struct m
+ {
+       struct nand_chip *this = mtd->priv;
+-      if (!this->bbt)
+-              return this->block_bad(mtd, ofs, getchip);
++      if (this->block_bad(mtd, ofs, getchip))
++              return 1;
+       /* Return info from the table */
+-      return nand_isbad_bbt (mtd, ofs, allowbbt);
++      if (this->bbt && nand_isbad_bbt (mtd, ofs, allowbbt))
++              return 1;
++
++      return 0;
+ }
+ /**
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-createbbt.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-createbbt.patch
new file mode 100644 (file)
index 0000000..74b79da
--- /dev/null
@@ -0,0 +1,126 @@
+This patch adds user-requested BBT creation. It includes the following changes:
+
+- common/cmd_nand.c: move yes/no decision to separate function
+- do_nand: ask for confirmation for "nand erase"
+- do_nand: add command "nand createbbt" to erase NAND and create a new BBT
+
+Experimental.
+
+- Werner Almesberger <werner@openmoko.org>
+
+
+Index: u-boot/common/cmd_nand.c
+===================================================================
+--- u-boot.orig/common/cmd_nand.c      2007-02-16 23:53:28.000000000 +0100
++++ u-boot/common/cmd_nand.c   2007-02-16 23:53:57.000000000 +0100
+@@ -163,6 +163,17 @@
+       return 0;
+ }
++static int yes(void)
++{
++      char c;
++
++      c = getc();
++      if (c != 'y' && c != 'Y')
++              return 0;
++      c = getc();
++      return c == '\r' || c == '\n';
++}
++
+ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+ {
+       int i, dev, ret;
+@@ -228,7 +239,8 @@
+           strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 &&
+           strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 &&
+           strcmp(cmd, "biterr") != 0 &&
+-          strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 )
++          strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 &&
++          strcmp(cmd, "createbbt") != 0 )
+               goto usage;
+       /* the following commands operate on the current device */
+@@ -283,13 +295,23 @@
+                            "are sure of what you are doing!\n"
+                            "\nReally scrub this NAND flash? <y/N>\n");
+-                      if (getc() == 'y' && getc() == '\r') {
++                      if (yes()) {
+                               opts.scrub = 1;
+                       } else {
+                               puts("scrub aborted\n");
+                               return -1;
+                       }
+               }
++              else {
++                      if (opts.length == nand->size) {
++                              puts("Really erase everything ? <y/N>\n");
++                              if (!yes()) {
++                                      puts("erase aborted\n");
++                                      return -1;
++                              }
++                      }
++              }
++
+               ret = nand_erase_opts(nand, &opts);
+               printf("%s\n", ret ? "ERROR" : "OK");
+@@ -458,6 +480,33 @@
+               return 0;
+       }
++      if (strcmp(cmd, "createbbt") == 0) {
++              struct nand_chip *nand_chip = nand->priv;
++              nand_erase_options_t opts;
++
++              puts("Create BBT and erase everything ? <y/N>\n");
++              if (!yes()) {
++                      puts("createbbt aborted\n");
++                      return -1;
++              }
++              memset(&opts, 0, sizeof(opts));
++              opts.length = nand->size;
++              if (nand_erase_opts(nand, &opts)) {
++                      puts("Erase failed\n");
++                      return 1;
++              }
++              nand_chip->options &= ~NAND_DONT_CREATE_BBT;
++              puts("Creating BBT. Please wait ...");
++              if (nand_default_bbt(nand)) {
++                      puts("\nFailed\n");
++                      return 1;
++              }
++              else {
++                      puts("\n");
++                      return 0;
++              }
++      }
++
+ usage:
+       printf("Usage:\n%s\n", cmdtp->usage);
+       return 1;
+@@ -478,7 +527,8 @@
+       "nand markbad off - mark bad block at offset (UNSAFE)\n"
+       "nand biterr off - make a bit error at offset (UNSAFE)\n"
+       "nand lock [tight] [status] - bring nand to lock state or display locked pages\n"
+-      "nand unlock [offset] [size] - unlock section\n");
++      "nand unlock [offset] [size] - unlock section\n"
++      "nand createbbt - create bad block table\n");
+ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
+                          ulong offset, ulong addr, char *cmd)
+Index: u-boot/drivers/nand/nand_bbt.c
+===================================================================
+--- u-boot.orig/drivers/nand/nand_bbt.c        2007-02-16 23:53:54.000000000 +0100
++++ u-boot/drivers/nand/nand_bbt.c     2007-02-16 23:53:57.000000000 +0100
+@@ -795,7 +795,8 @@
+       len = mtd->size >> (this->bbt_erase_shift + 2);
+       /* Allocate memory (2bit per block) */
+-      this->bbt = kmalloc (len, GFP_KERNEL);
++      if (!this->bbt)
++              this->bbt = kmalloc (len, GFP_KERNEL);
+       if (!this->bbt) {
+               printk (KERN_ERR "nand_scan_bbt: Out of memory\n");
+               return -ENOMEM;
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-dynamic_partitions.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-dynamic_partitions.patch
new file mode 100644 (file)
index 0000000..ecce004
--- /dev/null
@@ -0,0 +1,354 @@
+This patch adds support for 'dynamic partitions'.  This basically 
+works as follows:
+* The nand code generates a bad-block-table at the first scan of the chip
+* The dynamic partition code calculates the raw partition sizes based on 
+  the bad block table.  E.g. if you have a partition of size 0x30000, and there are 
+  two bad blocks (0x4000 each) in it, the raw size will increase to 0x38000, and the
+  following partitions get shifted towards the end of flash.
+
+Please note that currently the desired partition sizes are stored at compile-time
+in an array in drivers/nand/nand_bbt.c, so this definitely needs to change before
+submitting/merging upstream.
+
+In order to calculate the partiton map (and set mtdparts accordingly), you can use
+the 'dynpart' command at the prompt.  Use 'saveenv' to make the setting permanent.
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+
+Index: u-boot/drivers/nand/nand_bbt.c
+===================================================================
+--- u-boot.orig/drivers/nand/nand_bbt.c
++++ u-boot/drivers/nand/nand_bbt.c
+@@ -1044,9 +1044,86 @@
+       switch ((int)res) {
+       case 0x00:      return 0;
+       case 0x01:      return 1;
++      case 0x03:      return 1;
+       case 0x02:      return allowbbt ? 0 : 1;
+       }
+       return 1;
+ }
++#if defined(CONFIG_NAND_DYNPART)
++
++extern unsigned int dynpart_size[];
++extern char *dynpart_names[];
++
++#define MTDPARTS_MAX_SIZE 512
++
++
++static int skip_offs(const struct nand_chip *this, unsigned int offs)
++{
++      int block = (int) (offs >> (this->bbt_erase_shift - 1));
++      u_int8_t bbt = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
++
++      return bbt == 3;
++}
++
++int nand_create_mtd_dynpart(struct mtd_info *mtd)
++{
++      struct nand_chip *this = mtd->priv;
++      int part;
++      char *mtdparts;
++      unsigned int cur_offs = 0;
++
++      mtdparts = malloc(MTDPARTS_MAX_SIZE); /* FIXME: bounds checking */
++      if (!mtdparts)
++              return -ENOMEM;
++
++      sprintf(mtdparts, "mtdparts=" CFG_NAND_DYNPART_MTD_KERNEL_NAME ":");
++
++      for (part = 0; dynpart_size[part] != 0; part++) {
++              unsigned int bb_delta = 0;
++              unsigned int offs = 0;
++              char mtdpart[32];
++
++              for (offs = cur_offs;
++                   offs < cur_offs + dynpart_size[part] + bb_delta;
++                   offs += mtd->erasesize) {
++                      if (skip_offs(this, offs))
++                              bb_delta += mtd->erasesize;
++              }
++
++              /*
++               * Absorb bad blocks immediately following this partition also
++               * into the partition, in order to make next partition start
++               * with a good block. This simplifies handling of the
++               * environment partition.
++               */
++              while (offs < this->chipsize && skip_offs(this, offs)) {
++                      bb_delta += mtd->erasesize;
++                      offs += mtd->erasesize;
++              }
++
++              if (cur_offs + dynpart_size[part] + bb_delta > this->chipsize)
++                      dynpart_size[part] = this->chipsize - cur_offs - bb_delta;
++#if 0
++              printf("partition %u: start = 0x%08x, end=%08x size=%08x, size_inc_bb=%08x\n",
++                      part, cur_offs, cur_offs + dynpart_size[part] + bb_delta,
++                      dynpart_size[part], dynpart_size[part] + bb_delta);
++#endif
++              cur_offs += dynpart_size[part] + bb_delta;
++              sprintf(mtdpart, "0x%.8x(%.16s),", dynpart_size[part] + bb_delta,
++                      dynpart_names[part]);
++              mtdpart[sizeof(mtdpart)-1] = '\0';
++              strncat(mtdparts, mtdpart,
++                  MTDPARTS_MAX_SIZE-strlen(mtdparts)-1);
++      }
++
++      mtdparts[strlen(mtdparts)-1] = '\0';
++      printf("mtdparts %s\n", mtdparts);
++      setenv("mtdparts", mtdparts);
++
++      free(mtdparts);
++      return 0;
++}
++#endif /* CONFIG_NAND_DYNPART */
++
+ #endif
+Index: u-boot/include/configs/neo1973_gta01.h
+===================================================================
+--- u-boot.orig/include/configs/neo1973_gta01.h
++++ u-boot/include/configs/neo1973_gta01.h
+@@ -99,7 +99,7 @@
+                       CFG_CMD_ELF      | \
+                       CFG_CMD_MISC     | \
+                       /* CFG_CMD_USB   | */ \
+-                      /* CFG_CMD_JFFS2         | */ \
++                      CFG_CMD_JFFS2    | \
+                       CFG_CMD_DIAG     | \
+                       /* CFG_CMD_HWFLOW        | */ \
+                       CFG_CMD_SAVES    | \
+@@ -212,13 +212,13 @@
+ #define CONFIG_FAT            1
+ #define CONFIG_SUPPORT_VFAT
+-#if 0
++#if 1
+ /* JFFS2 driver */
+ #define CONFIG_JFFS2_CMDLINE  1
+ #define CONFIG_JFFS2_NAND     1
+ #define CONFIG_JFFS2_NAND_DEV 0
+-#define CONFIG_JFFS2_NAND_OFF 0x634000
+-#define CONFIG_JFFS2_NAND_SIZE        0x39cc000
++//#define CONFIG_JFFS2_NAND_OFF       0x634000
++//#define CONFIG_JFFS2_NAND_SIZE      0x39cc000
+ #endif
+ /* ATAG configuration */
+@@ -257,4 +257,9 @@
+ #define CONFIG_DRIVER_PCF50606                1
++#define MTDIDS_DEFAULT        "nand0=neo1973-nand"
++#define MTPARTS_DEFAULT       "neo1973-nand:256k(u-boot),16k(u-boot_env),2M(kernel),640k(splash),-(jffs2)"
++#define CFG_NAND_DYNPART_MTD_KERNEL_NAME "neo1973-nand"
++#define CONFIG_NAND_DYNPART
++
+ #endif        /* __CONFIG_H */
+Index: u-boot/common/cmd_jffs2.c
+===================================================================
+--- u-boot.orig/common/cmd_jffs2.c
++++ u-boot/common/cmd_jffs2.c
+@@ -1841,6 +1841,29 @@
+       return NULL;
+ }
++/* Return the 'net size' of the partition (i.e. excluding any bad blocks) */
++unsigned int nand_net_part_size(struct part_info *part)
++{
++      struct mtd_info *mtd;
++      unsigned int offs;
++      unsigned int bb_delta = 0;
++
++      if (!part || !part->dev || !part->dev->id ||
++          part->dev->id->num >= CFG_MAX_NAND_DEVICE)
++              return 0;
++
++      mtd = &nand_info[part->dev->id->num];
++
++      for (offs = part->offset; offs < part->offset + part->size;
++           offs += mtd->erasesize) {
++              if (nand_isbad_bbt(mtd, offs, 0))
++                      bb_delta += mtd->erasesize;
++      }
++
++      return part->size - bb_delta;
++}
++
++
+ /***************************************************/
+ /* U-boot commands                               */
+ /***************************************************/
+@@ -2132,6 +2155,24 @@
+       printf ("Usage:\n%s\n", cmdtp->usage);
+       return 1;
+ }
++
++#if defined(CONFIG_NAND_DYNPART)
++extern int nand_create_mtd_dynpart(struct mtd_info *mtd);
++
++int do_dynpart(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++#if 0
++      int i = simple_strtoul(argv[1], NULL, 0);
++      if (i >= CFG_MAX_NAND_DEVICE)
++              return -EINVAL;
++#endif
++      nand_create_mtd_dynpart(&nand_info[0]);
++
++      return 0;
++}
++#endif /* CONFIG_NAND_DYNPART */
++
++
+ #endif /* #ifdef CONFIG_JFFS2_CMDLINE */
+ /***************************************************/
+@@ -2197,6 +2238,15 @@
+       "<name>     := '(' NAME ')'\n"
+       "<ro-flag>  := when set to 'ro' makes partition read-only (not used, passed to kernel)\n"
+ );
++
++#if defined(CONFIG_NAND_DYNPART)
++U_BOOT_CMD(
++      dynpart, 1,     1,      do_dynpart,
++      "dynpart\t- dynamically calculate partition table based on BBT\n",
++      "\n"
++      "    - sets 'mtdparts' according to BBT\n");
++#endif /* CONFIG_NAND_DYNPART */
++
+ #endif /* #ifdef CONFIG_JFFS2_CMDLINE */
+ /***************************************************/
+Index: u-boot/common/cmd_nand.c
+===================================================================
+--- u-boot.orig/common/cmd_nand.c
++++ u-boot/common/cmd_nand.c
+@@ -101,7 +101,7 @@
+ }
+ int
+-arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size)
++arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size, int net)
+ {
+       int idx = nand_curr_device;
+ #if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
+@@ -122,10 +122,17 @@
+                                       printf("'%s' is not a number\n", argv[1]);
+                                       return -1;
+                               }
+-                              if (*size > part->size)
+-                                      *size = part->size;
++                              if (*size > part->size) {
++                                      if (net)
++                                              *size = nand_net_part_size(part);
++                                      else
++                                              *size = part->size;
++                              }
+                       } else {
+-                              *size = part->size;
++                              if (net)
++                                      *size = nand_net_part_size(part);
++                              else
++                                      *size = part->size;
+                       }
+                       idx = dev->id->num;
+                       *nand = nand_info[idx];
+@@ -261,7 +268,7 @@
+               printf("\nNAND %s: ", scrub ? "scrub" : "erase");
+               /* skip first two or three arguments, look for offset and size */
+-              if (arg_off_size(argc - o, argv + o, nand, &off, &size) != 0)
++              if (arg_off_size(argc - o, argv + o, nand, &off, &size, 0) != 0)
+                       return 1;
+               memset(&opts, 0, sizeof(opts));
+@@ -323,7 +330,7 @@
+               read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
+               printf("\nNAND %s: ", read ? "read" : "write");
+-              if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0)
++              if (arg_off_size(argc - 3, argv + 3, nand, &off, &size, 1) != 0)
+                       return 1;
+               s = strchr(cmd, '.');
+@@ -445,7 +452,7 @@
+       }
+       if (strcmp(cmd, "unlock") == 0) {
+-              if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0)
++              if (arg_off_size(argc - 2, argv + 2, nand, &off, &size, 0) < 0)
+                       return 1;
+               if (!nand_unlock(nand, off, size)) {
+Index: u-boot/common/cmd_dynenv.c
+===================================================================
+--- u-boot.orig/common/cmd_dynenv.c
++++ u-boot/common/cmd_dynenv.c
+@@ -60,7 +60,7 @@
+               buf[2] = 'V';
+               buf[3] = '0';
+-              if (arg_off_size(argc-2, argv+2, mtd, &addr, &dummy) < 0) {
++              if (arg_off_size(argc-2, argv+2, mtd, &addr, &dummy, 1) < 0) {
+                       printf("Offset or partition name expected\n");
+                       goto fail;
+               }
+Index: u-boot/include/util.h
+===================================================================
+--- u-boot.orig/include/util.h
++++ u-boot/include/util.h
+@@ -28,6 +28,6 @@
+ /* common/cmd_nand.c */
+ int arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off,
+-  ulong *size);
++  ulong *size, int net);
+ #endif /* UTIL_H */
+Index: u-boot/board/qt2410/qt2410.c
+===================================================================
+--- u-boot.orig/board/qt2410/qt2410.c
++++ u-boot/board/qt2410/qt2410.c
+@@ -126,3 +126,9 @@
+       return 0;
+ }
++
++unsigned int dynpart_size[] = {
++    CFG_UBOOT_SIZE, 0x4000, 0x200000, 0xa0000, 0x3d5c000-CFG_UBOOT_SIZE, 0 };
++char *dynpart_names[] = {
++    "u-boot", "u-boot_env", "kernel", "splash", "rootfs", NULL };
++
+Index: u-boot/board/neo1973/gta01/gta01.c
+===================================================================
+--- u-boot.orig/board/neo1973/gta01/gta01.c
++++ u-boot/board/neo1973/gta01/gta01.c
+@@ -429,3 +434,14 @@
+       return 0;
+ }
++
++/* The sum of all part_size[]s must equal to the NAND size, i.e., 0x4000000.
++   "initrd" is sized such that it can hold two uncompressed 16 bit 640*480
++   images: 640*480*2*2 = 1228800 < 1245184. */
++
++unsigned int dynpart_size[] = {
++    CFG_UBOOT_SIZE, 0x4000, 0x200000, 0xa0000, 0x3d5c000-CFG_UBOOT_SIZE, 0 };
++char *dynpart_names[] = {
++    "u-boot", "u-boot_env", "kernel", "splash", "rootfs", NULL };
++
++
+Index: u-boot/include/configs/qt2410.h
+===================================================================
+--- u-boot.orig/include/configs/qt2410.h
++++ u-boot/include/configs/qt2410.h
+@@ -283,5 +283,7 @@
+ #define MTDIDS_DEFAULT                "nand0=qt2410-nand"
+ #define MTPARTS_DEFAULT               "qt2410-nand:192k(u-boot),8k(u-boot_env),2M(kernel),2M(splash),-(jffs2)"
++#define CFG_NAND_DYNPART_MTD_KERNEL_NAME "qt2410-nand"
++#define CONFIG_NAND_DYNPART
+ #endif        /* __CONFIG_H */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-otp.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-otp.patch
new file mode 100644 (file)
index 0000000..b0e9bf4
--- /dev/null
@@ -0,0 +1,302 @@
+Index: u-boot/common/cmd_nand.c
+===================================================================
+--- u-boot.orig/common/cmd_nand.c
++++ u-boot/common/cmd_nand.c
+@@ -392,6 +392,14 @@
+                       else
+                               ret = nand->write_oob(nand, off, size, &size, 
+                                                     (u_char *) addr);
++              } else if (s != NULL && !strcmp(s, ".otp")) {
++                      /* read out-of-band data */
++                      if (read)
++                              ret = nand->read_otp(nand, off, size, &size,
++                                                   (u_char *) addr);
++                      else
++                              ret = nand->write_otp(nand, off, size, &size,
++                                                    (u_char *) addr);
+               } else {
+                       if (read)
+                               ret = nand_read(nand, off, &size, (u_char *)addr);
+@@ -527,8 +535,9 @@
+       "nand    - NAND sub-system\n",
+       "info                  - show available NAND devices\n"
+       "nand device [dev]     - show or set current device\n"
+-      "nand read[.jffs2]     - addr off|partition size\n"
+-      "nand write[.jffs2]    - addr off|partiton size - read/write `size' bytes starting\n"
++      "nand read[.jffs2, .oob, .otp] addr off|partition size\n"
++      "nand write[.jffs2, .oob, .otp] addr off|partiton size\n"
++      "  - read/write `size' bytes starting\n"
+       "    at offset `off' to/from memory address `addr'\n"
+       "nand erase [clean] [off size] - erase `size' bytes from\n"
+       "    offset `off' (entire device if not specified)\n"
+Index: u-boot/cpu/arm920t/s3c24x0/nand.c
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/nand.c
++++ u-boot/cpu/arm920t/s3c24x0/nand.c
+@@ -205,7 +205,7 @@
+ }
+ #endif
+-int board_nand_init(struct nand_chip *nand)
++int s3c24x0_nand_init(struct nand_chip *nand)
+ {
+       u_int32_t cfg;
+       u_int8_t tacls, twrph0, twrph1;
+Index: u-boot/drivers/nand/nand_base.c
+===================================================================
+--- u-boot.orig/drivers/nand/nand_base.c
++++ u-boot/drivers/nand/nand_base.c
+@@ -2042,6 +2042,32 @@
+ }
+ #endif
++/*
++ * See nand_read_oob and nand_write_oob
++ */
++
++static int nand_read_otp(struct mtd_info *mtd, loff_t from, size_t len,
++    size_t *retlen, u_char *buf)
++{
++      struct nand_chip *this = mtd->priv;
++
++      if (!this->read_otp)
++              return -ENOSYS;
++      return this->read_otp(mtd, from, len, retlen, buf);
++
++}
++
++static int nand_write_otp(struct mtd_info *mtd, loff_t to, size_t len,
++    size_t *retlen, const u_char *buf)
++{
++      struct nand_chip *this = mtd->priv;
++
++      if (!this->write_otp)
++              return -ENOSYS;
++      return this->write_otp(mtd, to, len, retlen, buf);
++}
++
++
+ /**
+  * single_erease_cmd - [GENERIC] NAND standard block erase command function
+  * @mtd:      MTD device structure
+@@ -2613,6 +2639,8 @@
+       mtd->write_ecc = nand_write_ecc;
+       mtd->read_oob = nand_read_oob;
+       mtd->write_oob = nand_write_oob;
++      mtd->read_otp = nand_read_otp;
++      mtd->write_otp = nand_write_otp;
+ /* XXX U-BOOT XXX */
+ #if 0
+       mtd->readv = NULL;
+Index: u-boot/include/linux/mtd/mtd.h
+===================================================================
+--- u-boot.orig/include/linux/mtd/mtd.h
++++ u-boot/include/linux/mtd/mtd.h
+@@ -95,6 +95,9 @@
+       int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
+       int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
++      int (*read_otp) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
++      int (*write_otp) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
++
+       /*
+        * Methods to access the protection register area, present in some
+        * flash devices. The user data is one time programmable but the
+Index: u-boot/include/linux/mtd/nand.h
+===================================================================
+--- u-boot.orig/include/linux/mtd/nand.h
++++ u-boot/include/linux/mtd/nand.h
+@@ -307,6 +307,10 @@
+       void            (*enable_hwecc)(struct mtd_info *mtd, int mode);
+       void            (*erase_cmd)(struct mtd_info *mtd, int page);
+       int             (*scan_bbt)(struct mtd_info *mtd);
++      int             (*read_otp)(struct mtd_info *mtd, loff_t from,
++                          size_t len, size_t *retlen, u_char *buf);
++        int           (*write_otp) (struct mtd_info *mtd, loff_t to,
++                          size_t len, size_t *retlen, const u_char *buf);
+       int             eccmode;
+       int             eccsize;
+       int             eccbytes;
+Index: u-boot/board/neo1973/gta01/Makefile
+===================================================================
+--- u-boot.orig/board/neo1973/gta01/Makefile
++++ u-boot/board/neo1973/gta01/Makefile
+@@ -25,7 +25,7 @@
+ LIB   = lib$(BOARD).a
+-OBJS  := gta01.o pcf50606.o ../common/cmd_neo1973.o ../common/jbt6k74.o ../common/udc.o ../common/bootmenu.o
++OBJS  := gta01.o pcf50606.o nand.o ../common/cmd_neo1973.o ../common/jbt6k74.o ../common/udc.o ../common/bootmenu.o
+ SOBJS := ../common/lowlevel_init.o
+ .PHONY:       all
+Index: u-boot/board/neo1973/gta01/nand.c
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/gta01/nand.c
+@@ -0,0 +1,121 @@
++/*
++ * nand.c - Board-specific NAND setup
++ *
++ * Copyright (C) 2007 by OpenMoko, Inc.
++ * Written by Werner Almesberger <werner@openmoko.org>
++ * All Rights Reserved
++ *
++ * 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" /* nand.h needs NAND_MAX_CHIPS */
++#include "linux/mtd/mtd.h"
++#include "linux/mtd/nand.h"
++#include "asm/errno.h"
++
++
++int s3c24x0_nand_init(struct nand_chip *nand);
++
++
++static void samsung_nand_begin_otp(struct mtd_info *mtd)
++{
++      struct nand_chip *this = mtd->priv;
++
++      /* @@@FIXME: this is ugly - we select the NAND chip to send the
++         mode switch commands, knowing that it will be switched off later */
++      this->select_chip(mtd, 0);
++      /* "magic" mode change */
++      this->cmdfunc(mtd, 0x30, -1, -1);
++      this->cmdfunc(mtd, 0x65, -1, -1);
++}
++
++
++static void samsung_nand_end_otp(struct mtd_info *mtd)
++{
++      struct nand_chip *this = mtd->priv;
++
++      /* read/write deselected the chip so now we need to select again */
++      this->select_chip(mtd, 0);
++      this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
++      this->select_chip(mtd, -1);
++}
++
++
++static loff_t otp_page[] = {
++      0x15,   /* 00-XX-00-00, with XX = 15h-19h */
++      0x16,
++      0x17,
++      0x18,
++      0x19,
++      0x1b,   /* 00-1B-00-00 */
++};
++
++#define OTP_PAGES (sizeof(otp_page)/sizeof(*otp_page))
++
++
++static int convert_otp_address(loff_t *addr, size_t *len)
++{
++      int page;
++
++      if (*len && *addr >> 9 != (*addr+*len-1) >> 9)
++              return -EINVAL;
++      if (*len > 512)
++              return -EINVAL;
++      page = *addr >> 9;
++      if (page >= OTP_PAGES)
++              return -EINVAL;
++      *addr = otp_page[page] << 9;
++      return 0;
++}
++
++
++static int samsung_nand_read_otp(struct mtd_info *mtd, loff_t from,
++    size_t len, size_t *retlen, u_char *buf)
++{
++      int ret;
++
++      ret = convert_otp_address(&from, &len);
++      if (ret)
++              return ret;
++      samsung_nand_begin_otp(mtd);
++      ret = mtd->read(mtd, from, len, retlen, buf);
++      samsung_nand_end_otp(mtd);
++      return ret;
++}
++
++
++static int samsung_nand_write_otp(struct mtd_info *mtd, loff_t to,
++    size_t len, size_t *retlen, const u_char *buf)
++{
++      int ret;
++
++      ret = convert_otp_address(&to, &len);
++      if (ret)
++              return ret;
++      samsung_nand_begin_otp(mtd);
++      ret = mtd->write(mtd, to, len, retlen, buf);
++      samsung_nand_end_otp(mtd);
++      return ret;
++}
++
++
++int board_nand_init(struct nand_chip *nand)
++{
++      nand->read_otp = samsung_nand_read_otp;
++      nand->write_otp = samsung_nand_write_otp;
++      return s3c24x0_nand_init(nand);
++}
+Index: u-boot/board/neo1973/gta02/nand.c
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/gta02/nand.c
+@@ -0,0 +1,39 @@
++/*
++ * nand.c - Board-specific NAND setup
++ *
++ * Copyright (C) 2007 by OpenMoko, Inc.
++ * Written by Werner Almesberger <werner@openmoko.org>
++ * All Rights Reserved
++ *
++ * 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" /* nand.h needs NAND_MAX_CHIPS */
++#include "linux/mtd/mtd.h"
++#include "linux/mtd/nand.h"
++
++
++int s3c24x0_nand_init(struct nand_chip *nand);
++
++
++/* Add OTP et al later */
++
++
++int board_nand_init(struct nand_chip *nand)
++{
++      return s3c24x0_nand_init(nand);
++}
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-read_write_oob.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-read_write_oob.patch
new file mode 100644 (file)
index 0000000..8360409
--- /dev/null
@@ -0,0 +1,23 @@
+Re-introduce the 'nand read.oob' and 'nand write.oob' commands
+that used to exist with the legacy NAND code
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+Index: u-boot.git/common/cmd_nand.c
+===================================================================
+--- u-boot.git.orig/common/cmd_nand.c  2007-01-26 15:41:13.000000000 +0100
++++ u-boot.git/common/cmd_nand.c       2007-01-26 15:49:37.000000000 +0100
+@@ -351,6 +351,14 @@
+                               opts.quiet      = quiet;
+                               ret = nand_write_opts(nand, &opts);
+                       }
++              } else if (s != NULL && !strcmp(s, ".oob")) {
++                      /* read out-of-band data */
++                      if (read)
++                              ret = nand->read_oob(nand, off, size, &size,
++                                                   (u_char *) addr);
++                      else
++                              ret = nand->write_oob(nand, off, size, &size, 
++                                                    (u_char *) addr);
+               } else {
+                       if (read)
+                               ret = nand_read(nand, off, &size, (u_char *)addr);
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/neo1973-chargefast.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/neo1973-chargefast.patch
new file mode 100644 (file)
index 0000000..6f6af2c
--- /dev/null
@@ -0,0 +1,316 @@
+Index: u-boot/drivers/usbtty.c
+===================================================================
+--- u-boot.orig/drivers/usbtty.c
++++ u-boot/drivers/usbtty.c
+@@ -66,7 +66,7 @@
+ /*
+  * Defines
+  */
+-#define NUM_CONFIGS    1
++#define NUM_CONFIGS    2
+ #define MAX_INTERFACES 2
+ #define NUM_ENDPOINTS  3
+ #define ACM_TX_ENDPOINT 3
+@@ -192,8 +192,7 @@
+ #endif
+                       .bConfigurationValue = 1,
+                       .iConfiguration = STR_CONFIG,
+-                      .bmAttributes = 
+-                              BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
++                      .bmAttributes = BMATTRIBUTE_RESERVED,
+                       .bMaxPower = USBTTY_MAXPOWER
+               },
+               /* Interface 1 */
+@@ -294,6 +293,120 @@
+               .func_dfu = DFU_FUNC_DESC,
+ #endif
+       },
++      {
++              .configuration_desc ={
++                      .bLength = 
++                              sizeof(struct usb_configuration_descriptor),
++                      .bDescriptorType = USB_DT_CONFIG,
++                      .wTotalLength =  
++                              cpu_to_le16(sizeof(struct acm_config_desc)
++#ifdef CONFIG_USBD_DFU
++                                          - sizeof(struct usb_interface_descriptor)
++                                          - sizeof(struct usb_dfu_func_descriptor)
++#endif
++                                         ),
++                      .bNumInterfaces = NUM_ACM_INTERFACES,
++                      .bConfigurationValue = 2,
++                      .iConfiguration = STR_CONFIG,
++                      .bmAttributes = BMATTRIBUTE_RESERVED,
++                      .bMaxPower = 50, /* 100mA */
++              },
++              /* Interface 1 */
++              .interface_desc = {
++                      .bLength  = sizeof(struct usb_interface_descriptor),
++                      .bDescriptorType = USB_DT_INTERFACE,
++                      .bInterfaceNumber = 0,
++                      .bAlternateSetting = 0,
++                      .bNumEndpoints = 0x01,
++                      .bInterfaceClass = 
++                              COMMUNICATIONS_INTERFACE_CLASS_CONTROL,
++                      .bInterfaceSubClass = COMMUNICATIONS_ACM_SUBCLASS,
++                      .bInterfaceProtocol = COMMUNICATIONS_V25TER_PROTOCOL,
++                      .iInterface = STR_CTRL_INTERFACE,
++              },
++              .usb_class_header = {
++                      .bFunctionLength        = 
++                              sizeof(struct usb_class_header_function_descriptor),
++                      .bDescriptorType        = CS_INTERFACE, 
++                      .bDescriptorSubtype     = USB_ST_HEADER,
++                      .bcdCDC = cpu_to_le16(110),
++              },
++              .usb_class_call_mgt = {
++                      .bFunctionLength        = 
++                              sizeof(struct usb_class_call_management_descriptor),
++                      .bDescriptorType        = CS_INTERFACE,
++                      .bDescriptorSubtype     = USB_ST_CMF,
++                      .bmCapabilities         = 0x00, 
++                      .bDataInterface         = 0x01, 
++              },
++              .usb_class_acm = {
++                      .bFunctionLength        = 
++                              sizeof(struct usb_class_abstract_control_descriptor),
++                      .bDescriptorType        = CS_INTERFACE,
++                      .bDescriptorSubtype     = USB_ST_ACMF,  
++                      .bmCapabilities         = 0x00, 
++              },
++              .usb_class_union = {
++                      .bFunctionLength        =       
++                              sizeof(struct usb_class_union_function_descriptor),
++                      .bDescriptorType        = CS_INTERFACE,
++                      .bDescriptorSubtype     = USB_ST_UF,
++                      .bMasterInterface       = 0x00, 
++                      .bSlaveInterface0       = 0x01, 
++              },
++              .notification_endpoint = {
++                      .bLength =              
++                              sizeof(struct usb_endpoint_descriptor),
++                      .bDescriptorType        = USB_DT_ENDPOINT,
++                      .bEndpointAddress       = 0x01 | USB_DIR_IN,
++                      .bmAttributes           = USB_ENDPOINT_XFER_INT,
++                      .wMaxPacketSize         
++                              = cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
++                      .bInterval              = 0xFF,
++              },
++
++              /* Interface 2 */
++              .data_class_interface = {
++                      .bLength                = 
++                              sizeof(struct usb_interface_descriptor),
++                      .bDescriptorType        = USB_DT_INTERFACE,
++                      .bInterfaceNumber       = 0x01,
++                      .bAlternateSetting      = 0x00,
++                      .bNumEndpoints          = 0x02,
++                      .bInterfaceClass        = 
++                              COMMUNICATIONS_INTERFACE_CLASS_DATA,
++                      .bInterfaceSubClass     = DATA_INTERFACE_SUBCLASS_NONE,
++                      .bInterfaceProtocol     = DATA_INTERFACE_PROTOCOL_NONE,
++                      .iInterface             = STR_DATA_INTERFACE,
++              },
++              .data_endpoints = {
++                      {
++                              .bLength                = 
++                                      sizeof(struct usb_endpoint_descriptor),
++                              .bDescriptorType        = USB_DT_ENDPOINT,
++                              .bEndpointAddress       = 0x02 | USB_DIR_OUT,
++                              .bmAttributes           = 
++                                      USB_ENDPOINT_XFER_BULK,
++                              .wMaxPacketSize         = 
++                                      cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
++                              .bInterval              = 0xFF,
++                      },
++                      {
++                              .bLength                = 
++                                      sizeof(struct usb_endpoint_descriptor),
++                              .bDescriptorType        = USB_DT_ENDPOINT,
++                              .bEndpointAddress       = 0x03 | USB_DIR_IN,
++                              .bmAttributes           = 
++                                      USB_ENDPOINT_XFER_BULK,
++                              .wMaxPacketSize         = 
++                                      cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
++                              .bInterval              = 0xFF,
++                      },
++              },
++              /* We don't add the DFU functional descriptor here since we only
++               * want to do DFU in the high-current charging mode for safety reasons */
++      },
++
+ };    
+ static struct rs232_emu rs232_desc={
+@@ -330,8 +443,7 @@
+                       .bNumInterfaces = NUM_GSERIAL_INTERFACES,
+                       .bConfigurationValue = 1,
+                       .iConfiguration = STR_CONFIG,
+-                      .bmAttributes = 
+-                              BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
++                      .bmAttributes = BMATTRIBUTE_RESERVED,
+                       .bMaxPower = USBTTY_MAXPOWER
+               },
+               .interface_desc = {
+@@ -384,6 +496,68 @@
+                       },
+               },
+       },
++      {
++              .configuration_desc ={
++                      .bLength = sizeof(struct usb_configuration_descriptor),
++                      .bDescriptorType = USB_DT_CONFIG,
++                      .wTotalLength =  
++                              cpu_to_le16(sizeof(struct gserial_config_desc)),
++                      .bNumInterfaces = NUM_GSERIAL_INTERFACES,
++                      .bConfigurationValue = 1,
++                      .iConfiguration = STR_CONFIG,
++                      .bmAttributes = BMATTRIBUTE_RESERVED,
++                      .bMaxPower = 50
++              },
++              .interface_desc = {
++                      {
++                              .bLength  = 
++                                      sizeof(struct usb_interface_descriptor),
++                              .bDescriptorType = USB_DT_INTERFACE,
++                              .bInterfaceNumber = 0,
++                              .bAlternateSetting = 0,
++                              .bNumEndpoints = NUM_ENDPOINTS,
++                              .bInterfaceClass = 
++                                      COMMUNICATIONS_INTERFACE_CLASS_VENDOR,
++                              .bInterfaceSubClass = 
++                                      COMMUNICATIONS_NO_SUBCLASS,
++                              .bInterfaceProtocol = 
++                                      COMMUNICATIONS_NO_PROTOCOL,
++                              .iInterface = STR_DATA_INTERFACE
++                      },
++              },
++              .data_endpoints  = {
++                      {
++                              .bLength =              
++                                      sizeof(struct usb_endpoint_descriptor),
++                              .bDescriptorType =      USB_DT_ENDPOINT,
++                              .bEndpointAddress =     0x01 | USB_DIR_OUT,
++                              .bmAttributes =         USB_ENDPOINT_XFER_BULK,
++                              .wMaxPacketSize =       
++                                      cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE),
++                              .bInterval=             0xFF,
++                      },
++                      {
++                              .bLength =              
++                                      sizeof(struct usb_endpoint_descriptor),
++                              .bDescriptorType =      USB_DT_ENDPOINT,
++                              .bEndpointAddress =     0x02 | USB_DIR_IN,
++                              .bmAttributes =         USB_ENDPOINT_XFER_BULK,
++                              .wMaxPacketSize =       
++                                      cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE),
++                              .bInterval =            0xFF,
++                      },
++                      {
++                              .bLength =              
++                                      sizeof(struct usb_endpoint_descriptor),
++                              .bDescriptorType =      USB_DT_ENDPOINT,
++                              .bEndpointAddress =     0x03 | USB_DIR_IN,
++                              .bmAttributes =         USB_ENDPOINT_XFER_INT,
++                              .wMaxPacketSize =       
++                                      cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
++                              .bInterval =            0xFF,
++                      },
++              },
++      },
+ };
+ /*
+@@ -679,12 +853,14 @@
+       bus_instance->maxpacketsize = 64;
+       bus_instance->serial_number_str = serial_number;
+-      /* configuration instance */
+-      memset (config_instance, 0,
+-              sizeof (struct usb_configuration_instance));
+-      config_instance->interfaces = interface_count;
+-      config_instance->configuration_descriptor = configuration_descriptor;
+-      config_instance->interface_instance_array = interface_instance;
++      /* configuration instances */
++      for (i = 0; i < NUM_CONFIGS; i++) {
++              memset(&config_instance[i], 0, sizeof(config_instance));
++              config_instance[i].interfaces = interface_count;
++              /* FIXME: this breaks for the non-ACM case */
++              config_instance[i].configuration_descriptor = &acm_configuration_descriptors[i];
++              config_instance[i].interface_instance_array = interface_instance;
++      }
+       /* interface instance */
+       memset (interface_instance, 0,
+@@ -1043,9 +1219,17 @@
+               usbtty_configured_flag = 0;
+               break;
+       case DEVICE_CONFIGURED:
++              printf("DEVICE_CONFIGURED: %u\n", device->configuration);
++              if (device->configuration == 1)
++                      udc_ctrl(UDC_CTRL_500mA_ENABLE, 1);
++              else
++                      udc_ctrl(UDC_CTRL_500mA_ENABLE, 0);
+               usbtty_configured_flag = 1;
+               break;
+-
++      case DEVICE_DE_CONFIGURED:
++              printf("DEVICE_DE_CONFIGURED\n");
++              udc_ctrl(UDC_CTRL_500mA_ENABLE, 0);
++              break;
+       case DEVICE_ADDRESS_ASSIGNED:
+               usbtty_init_endpoints ();
+Index: u-boot/drivers/usbtty.h
+===================================================================
+--- u-boot.orig/drivers/usbtty.h
++++ u-boot/drivers/usbtty.h
+@@ -60,7 +60,7 @@
+ #define USBTTY_DEVICE_CLASS   COMMUNICATIONS_DEVICE_CLASS
+ #define USBTTY_BCD_DEVICE     0x00
+-#define USBTTY_MAXPOWER       0x00
++#define USBTTY_MAXPOWER       250     /* 500mA */
+ #define STR_LANG              0x00
+ #define STR_MANUFACTURER      0x01
+Index: u-boot/board/neo1973/common/udc.c
+===================================================================
+--- u-boot.orig/board/neo1973/common/udc.c
++++ u-boot/board/neo1973/common/udc.c
+@@ -2,6 +2,7 @@
+ #include <common.h>
+ #include <usbdcore.h>
+ #include <s3c2410.h>
++#include <pcf50606.h>
+ void udc_ctrl(enum usbd_event event, int param)
+ {
+@@ -17,6 +18,13 @@
+                       gpio->GPBDAT &= ~(1 << 9);
+ #endif
+               break;
++      case UDC_CTRL_500mA_ENABLE:
++#if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4) || \
++    defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3) || \
++    defined(CONFIG_ARCH_GTA01B_v4)
++              pcf50606_charge_autofast(param);
++#endif
++              break;
+       default:
+               break;
+       }
+Index: u-boot/include/usbdcore.h
+===================================================================
+--- u-boot.orig/include/usbdcore.h
++++ u-boot/include/usbdcore.h
+@@ -686,8 +686,8 @@
+ enum usbd_event {
+       UDC_CTRL_PULLUP_ENABLE,
++      UDC_CTRL_500mA_ENABLE,
+ };
+ void udc_ctrl(enum usbd_event event, int param);
+ #endif
+-#endif
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/preboot-override.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/preboot-override.patch
new file mode 100644 (file)
index 0000000..f32cbde
--- /dev/null
@@ -0,0 +1,137 @@
+Provide a place where the loader can patch the binary, such that it executes a
+command string from RAM. We use this for automated installs, where we can thus
+use the same u-boot binary for all stages.
+
+include/configs/neo1973.h: new option CFG_PREBOOT_OVERRIDE to allow setting of
+  the preboot command in memory
+cpu/arm920t/start.S: added variable "preboot_override" at known location
+  (_start+0x40)
+common/main.c (main_loop): if preboot_override is set, execute the command
+  string found there
+common/env_common.c (env_relocate):  if preboot_override is set, always use the
+  default environment
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/cpu/arm920t/start.S
+===================================================================
+--- u-boot.orig/cpu/arm920t/start.S
++++ u-boot/cpu/arm920t/start.S
+@@ -77,6 +77,14 @@ _fiq:                       .word fiq
+  *************************************************************************
+  */
++
++/* Must follow the .balign above, so we get a well-known address ! */
++#ifdef CFG_PREBOOT_OVERRIDE
++.globl        preboot_override
++preboot_override:
++      .word   0
++#endif
++
+ #ifdef CONFIG_S3C2410_NAND_BOOT
+ .globl        booted_from_nand
+ booted_from_nand:
+Index: u-boot/include/configs/neo1973_gta01.h
+===================================================================
+--- u-boot.orig/include/configs/neo1973_gta01.h
++++ u-boot/include/configs/neo1973_gta01.h
+@@ -207,6 +207,7 @@
+ #define       CFG_ENV_IS_IN_NAND      1
+ #define CFG_ENV_SIZE          0x4000          /* 16k Total Size of Environment Sector */
+ #define CFG_ENV_OFFSET_OOB    1               /* Location of ENV stored in block 0 OOB */
++#define       CFG_PREBOOT_OVERRIDE    1       /* allow preboot from memory */
+ #define NAND_MAX_CHIPS                1
+ #define CFG_NAND_BASE         0x4e000000
+Index: u-boot/common/main.c
+===================================================================
+--- u-boot.orig/common/main.c
++++ u-boot/common/main.c
+@@ -85,6 +85,11 @@ int do_mdm_init = 0;
+ extern void mdm_init(void); /* defined in board.c */
+ #endif
++#ifdef CFG_PREBOOT_OVERRIDE
++extern char *preboot_override;
++#endif
++
++
+ /***************************************************************************
+  * Watch for 'delay' seconds for autoboot stop or autoboot delay string.
+  * returns: 0 -  no key string, allow autoboot
+@@ -306,8 +311,8 @@ void main_loop (void)
+       char *s;
+       int bootdelay;
+ #endif
+-#ifdef CONFIG_PREBOOT
+-      char *p;
++#if defined(CONFIG_PREBOOT) || defined(CFG_PREBOOT_OVERRIDE)
++      char *p = NULL;
+ #endif
+ #ifdef CONFIG_BOOTCOUNT_LIMIT
+       unsigned long bootcount = 0;
+@@ -364,8 +369,23 @@ void main_loop (void)
+       install_auto_complete();
+ #endif
++#if defined(CONFIG_PREBOOT) || defined(CFG_PREBOOT_OVERRIDE)
+ #ifdef CONFIG_PREBOOT
+-      if ((p = getenv ("preboot")) != NULL) {
++      p = getenv ("preboot");
++#endif
++#ifdef CFG_PREBOOT_OVERRIDE
++      if (preboot_override) {
++              /* for convenience, preboot_override may end in \n, not \0 */
++              p = strchr(preboot_override, '\n');
++              if (p)
++                      *p = 0;
++              /* make sure we can overwrite the load area if we want to */
++              p = strdup(preboot_override);
++              /* clean the image in case we want to flash it */
++              preboot_override = NULL;
++      }
++#endif /* CFG_PREBOOT_OVERRIDE */
++      if (p) {
+ # ifdef CONFIG_AUTOBOOT_KEYED
+               int prev = disable_ctrlc(1);    /* disable Control C checking */
+ # endif
+@@ -381,7 +401,7 @@ void main_loop (void)
+               disable_ctrlc(prev);    /* restore Control C checking */
+ # endif
+       }
+-#endif /* CONFIG_PREBOOT */
++#endif /* CONFIG_PREBOOT || CFG_PREBOOT_OVERRIDE */
+ #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+       s = getenv ("bootdelay");
+Index: u-boot/common/env_common.c
+===================================================================
+--- u-boot.orig/common/env_common.c
++++ u-boot/common/env_common.c
+@@ -37,6 +37,10 @@
+ # define SHOW_BOOT_PROGRESS(arg)
+ #endif
++#ifdef CFG_PREBOOT_OVERRIDE
++extern char *preboot_override;
++#endif
++
+ DECLARE_GLOBAL_DATA_PTR;
+ #ifdef CONFIG_AMIGAONEG3SE
+@@ -234,7 +238,14 @@ void env_relocate (void)
+               puts ("*** Warning - bad CRC, using default environment\n\n");
+               SHOW_BOOT_PROGRESS (-1);
+ #endif
++      }
++
++#ifdef CFG_PREBOOT_OVERRIDE
++      if (preboot_override)
++              gd->env_valid = 0;
++#endif
++      if (gd->env_valid == 0) {
+               if (sizeof(default_environment) > ENV_SIZE)
+               {
+                       puts ("*** Error - default environment is too large\n\n");
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/raise-limits.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/raise-limits.patch
new file mode 100644 (file)
index 0000000..a1c381a
--- /dev/null
@@ -0,0 +1,31 @@
+include/configs/neo1973.h: increase heap from 128 kB to 400 kB, for BMP image
+  decompression
+  [ note: increasing it to 512 kB trips over something. note sure what.
+    find out. ]
+include/configs/neo1973.h: raise number of command line arguments from 16 to 64
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/include/configs/neo1973_gta01.h
+===================================================================
+--- u-boot.orig/include/configs/neo1973_gta01.h
++++ u-boot/include/configs/neo1973_gta01.h
+@@ -54,7 +54,8 @@
+ /*
+  * Size of malloc() pool
+  */
+-#define CFG_MALLOC_LEN                (CFG_ENV_SIZE + 128*1024)
++#define CFG_MALLOC_LEN                (CFG_ENV_SIZE + 400*1024)
++                                      /* >> CFG_VIDEO_LOGO_MAX_SIZE */
+ #define CFG_GBL_DATA_SIZE     128     /* size in bytes reserved for initial data */
+ /*
+@@ -142,7 +143,7 @@
+ #endif
+ #define       CFG_CBSIZE              256             /* Console I/O Buffer Size      */
+ #define       CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+-#define       CFG_MAXARGS             16              /* max number of command args   */
++#define       CFG_MAXARGS             64              /* max number of command args   */
+ #define CFG_BARGSIZE          CFG_CBSIZE      /* Boot Argument Buffer Size    */
+ #define CFG_MEMTEST_START     0x30000000      /* memtest works on     */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/series b/meta/packages/uboot/u-boot-mkimage-openmoko-native/series
new file mode 100644 (file)
index 0000000..4fc7d13
--- /dev/null
@@ -0,0 +1,76 @@
+# just some local hacks
+uboot-machtypes.patch
+ext2load_hex.patch
+uboot-mokoversion.patch
+
+# those we want to get mainline
+uboot-s3c2410-warnings-fix.patch
+uboot-strtoul.patch
+uboot-cramfs_but_no_jffs2.patch
+nand-read_write_oob.patch
+uboot-arm920t-gd_in_irq.patch
+uboot-arm920_s3c2410_irq_demux.patch
+uboot-s3c2410-nand.patch
+uboot-cmd_s3c2410.patch
+uboot-s3c2410-mmc.patch
+env_nand_oob.patch
+dynenv-harden.patch
+uboot-s3c2410_fb.patch
+uboot-20061030-qt2410.patch 
+uboot-20061030-neo1973.patch 
+
+# under construction, but intended for mainline
+uboot-s3c2410-misccr-definitions.patch
+
+boot-from-ram-reloc.patch
+boot-from-ram-and-nand.patch
+wakeup-reason-nand-only.patch
+uboot-neo1973-resume.patch
+
+# this will be somewhat more difficult
+nand-dynamic_partitions.patch
+uboot-s3c2410-norelocate_irqvec_cpy.patch
+uboot-usbtty-acm.patch
+uboot-s3c2410_udc.patch
+
+# those need to be cleaned up
+bbt-create-optional.patch
+nand-createbbt.patch
+dontask.patch
+nand-badisbad.patch
+uboot-bbt-quiet.patch
+
+# splash screen
+raise-limits.patch
+splashimage-command.patch
+cmd-unzip.patch
+enable-splash-bmp.patch
+
+# for automated installation
+preboot-override.patch
+lowlevel_foo.patch
+
+# move these later, once the dust has settled
+default-env.patch
+console-ansi.patch
+boot-menu.patch
+
+# those have to be implemented fully
+uboot-dfu.patch
+uboot-neo1973-defaultenv.patch
+uboot-nand-markbad-reallybad.patch
+usbdcore-multiple_configs.patch
+neo1973-chargefast.patch
+
+uboot-s3c2440.patch
+uboot-smdk2440.patch
+uboot-hxd8.patch
+
+uboot-license.patch
+
+uboot-gta02.patch
+uboot-s3c2443.patch
+uboot-smdk2443.patch
+
+# for review, merge soon
+unbusy-i2c.patch 
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/splashimage-command.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/splashimage-command.patch
new file mode 100644 (file)
index 0000000..8ea48cf
--- /dev/null
@@ -0,0 +1,24 @@
+drivers/cfb_console.c (video_logo): if "splashimage" doesn't contain an
+  address, use its content as a command
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/drivers/cfb_console.c
+===================================================================
+--- u-boot.orig/drivers/cfb_console.c
++++ u-boot/drivers/cfb_console.c
+@@ -1121,7 +1121,13 @@ static void *video_logo (void)
+       ulong addr;
+       if ((s = getenv ("splashimage")) != NULL) {
+-              addr = simple_strtoul (s, NULL, 16);
++              char *end;
++
++              addr = simple_strtoul (s, &end, 16);
++              if (*end) {
++                      run_command(s, 0);
++                      return video_fb_address;
++              }
+               if (video_display_bitmap (addr, 0, 0) == 0) {
+                       return ((void *) (video_fb_address));
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-20061030-neo1973.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-20061030-neo1973.patch
new file mode 100644 (file)
index 0000000..7c70244
--- /dev/null
@@ -0,0 +1,2248 @@
+This patch adds neo1973 'board' (FIC Neo1973 phone) support to u-boot.
+Specifically, it adds support for the GTA01v3, GTA01v4, GTA01Bv2 and
+GTA01Bv3 hardware revisions.
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+
+Index: u-boot/Makefile
+===================================================================
+--- u-boot.orig/Makefile
++++ u-boot/Makefile
+@@ -2009,6 +2009,14 @@
+ sbc2410x_config: unconfig
+       @$(MKCONFIG) $(@:_config=) arm arm920t sbc2410x NULL s3c24x0
++gta01_config \
++gta01v3_config \
++gta01bv2_config \
++gta01bv3_config \
++gta01bv4_config \
++gta01v4_config :      unconfig
++      @sh board/neo1973/gta01/split_by_variant.sh $@
++
+ qt2410_config :       unconfig
+       @./mkconfig $(@:_config=) arm arm920t qt2410 NULL s3c24x0
+Index: u-boot/common/main.c
+===================================================================
+--- u-boot.orig/common/main.c
++++ u-boot/common/main.c
+@@ -61,6 +61,7 @@
+ #undef DEBUG_PARSER
+ char        console_buffer[CFG_CBSIZE];               /* console I/O buffer   */
++int nobootdelay;
+ #ifndef CONFIG_CMDLINE_EDITING
+ static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen);
+@@ -376,7 +377,7 @@
+       debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
+-      if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
++      if (!nobootdelay && bootdelay >= 0 && s && !abortboot (bootdelay)) {
+ # ifdef CONFIG_AUTOBOOT_KEYED
+               int prev = disable_ctrlc(1);    /* disable Control C checking */
+ # endif
+Index: u-boot/drivers/Makefile
+===================================================================
+--- u-boot.orig/drivers/Makefile
++++ u-boot/drivers/Makefile
+@@ -50,6 +50,7 @@
+         usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \
+         videomodes.o w83c553f.o \
+         ks8695eth.o \
++        pcf50606.o \
+         pxa_pcmcia.o mpc8xx_pcmcia.o tqm8xx_pcmcia.o  \
+         rpx_pcmcia.o \
+         fsl_i2c.o s3c2410_fb.o
+Index: u-boot/drivers/pcf50606.c
+===================================================================
+--- /dev/null
++++ u-boot/drivers/pcf50606.c
+@@ -0,0 +1,112 @@
++
++#include <common.h>
++
++#ifdef CONFIG_DRIVER_PCF50606
++
++#include <i2c.h>
++#include <pcf50606.h>
++#include <asm/atomic.h>
++#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
++
++#define PCF50606_I2C_ADDR             0x08
++
++void __pcf50606_reg_write(u_int8_t reg, u_int8_t val)
++{
++      i2c_write(PCF50606_I2C_ADDR, reg, 1, &val, 1);
++}
++
++u_int8_t __pcf50606_reg_read(u_int8_t reg)
++{
++      u_int8_t tmp;
++      i2c_read(PCF50606_I2C_ADDR, reg, 1, &tmp, 1);
++      return tmp;
++}
++
++void pcf50606_reg_write(u_int8_t reg, u_int8_t val)
++{
++      unsigned long flags;
++
++      local_irq_save(flags);
++      __pcf50606_reg_write(reg, val);
++      local_irq_restore(flags);
++}
++
++u_int8_t pcf50606_reg_read(u_int8_t reg)
++{
++      unsigned long flags;
++      u_int8_t tmp;
++
++      local_irq_save(flags);
++      tmp = __pcf50606_reg_read(reg);
++      local_irq_restore(flags);
++
++      return tmp;
++}
++
++void pcf50606_reg_set_bit_mask(u_int8_t reg, u_int8_t mask, u_int8_t val)
++{
++      unsigned long flags;
++      u_int8_t tmp;
++
++      local_irq_save(flags);
++      tmp = __pcf50606_reg_read(reg);
++      __pcf50606_reg_write(reg, (val & mask) | (tmp & ~mask));
++      local_irq_restore(flags);
++}
++
++void pcf50606_reg_clear_bits(u_int8_t reg, u_int8_t bits)
++{
++      unsigned long flags;
++      u_int8_t tmp;
++
++      local_irq_save(flags);
++      tmp = pcf50606_reg_read(reg);
++      pcf50606_reg_write(reg, (tmp & ~bits));
++      local_irq_restore(flags);
++}
++
++static const u_int8_t regs_valid[] = {
++      PCF50606_REG_OOCS, PCF50606_REG_INT1M, PCF50606_REG_INT2M,
++      PCF50606_REG_INT3M, PCF50606_REG_OOCC1, PCF50606_REG_OOCC2,
++      PCF50606_REG_PSSC, PCF50606_REG_PWROKM, PCF50606_REG_DCDC1,
++      PCF50606_REG_DCDC2, PCF50606_REG_DCDC3, PCF50606_REG_DCDC4,
++      PCF50606_REG_DCDEC1, PCF50606_REG_DCDEC2, PCF50606_REG_DCUDC1,
++      PCF50606_REG_DCUDC2, PCF50606_REG_IOREGC, PCF50606_REG_D1REGC1,
++      PCF50606_REG_D2REGC1, PCF50606_REG_D3REGC1, PCF50606_REG_LPREGC1,
++      PCF50606_REG_LPREGC2, PCF50606_REG_MBCC1, PCF50606_REG_MBCC2,
++      PCF50606_REG_MBCC3, PCF50606_REG_BBCC, PCF50606_REG_ADCC1,
++      PCF50606_REG_ADCC2, PCF50606_REG_ACDC1, PCF50606_REG_BVMC,
++      PCF50606_REG_PWMC1, PCF50606_REG_LEDC1, PCF50606_REG_LEDC2,
++      PCF50606_REG_GPOC1, PCF50606_REG_GPOC2, PCF50606_REG_GPOC3,
++      PCF50606_REG_GPOC4, PCF50606_REG_GPOC5,
++};
++
++
++/* initialize PCF50606 register set */
++void pcf50606_init(void)
++{
++      unsigned long flags;
++      int i;
++
++      local_irq_save(flags);
++      for (i = 0; i < ARRAY_SIZE(regs_valid); i++) {
++              __pcf50606_reg_write(regs_valid[i],
++                                   pcf50606_initial_regs[regs_valid[i]]);
++      }
++      local_irq_restore(flags);
++}
++
++void pcf50606_charge_autofast(int on)
++{
++      if (on) {
++              printf("Enabling automatic fast charge\n");
++              pcf50606_reg_set_bit_mask(PCF50606_REG_MBCC1,
++                                        PCF50606_MBCC1_AUTOFST,
++                                        PCF50606_MBCC1_AUTOFST);
++      } else {
++              printf("Disabling fast charge\n");
++              pcf50606_reg_write(PCF50606_REG_MBCC1, 0x00);
++      }
++}
++
++#endif /* CONFIG DRIVER_PCF50606 */
+Index: u-boot/include/pcf50606.h
+===================================================================
+--- /dev/null
++++ u-boot/include/pcf50606.h
+@@ -0,0 +1,273 @@
++#ifndef _PCF50606_H
++#define _PCF50606_H
++
++/* Philips PCF50606 Power Managemnt Unit (PMU) driver
++ * (C) 2006-2007 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ */
++
++enum pfc50606_regs {
++      PCF50606_REG_ID         = 0x00,
++      PCF50606_REG_OOCS       = 0x01,
++      PCF50606_REG_INT1       = 0x02, /* Interrupt Status */
++      PCF50606_REG_INT2       = 0x03, /* Interrupt Status */
++      PCF50606_REG_INT3       = 0x04, /* Interrupt Status */
++      PCF50606_REG_INT1M      = 0x05, /* Interrupt Mask */
++      PCF50606_REG_INT2M      = 0x06, /* Interrupt Mask */
++      PCF50606_REG_INT3M      = 0x07, /* Interrupt Mask */
++      PCF50606_REG_OOCC1      = 0x08,
++      PCF50606_REG_OOCC2      = 0x09,
++      PCF50606_REG_RTCSC      = 0x0a, /* Second */
++      PCF50606_REG_RTCMN      = 0x0b, /* Minute */
++      PCF50606_REG_RTCHR      = 0x0c, /* Hour */
++      PCF50606_REG_RTCWD      = 0x0d, /* Weekday */
++      PCF50606_REG_RTCDT      = 0x0e, /* Day */
++      PCF50606_REG_RTCMT      = 0x0f, /* Month */
++      PCF50606_REG_RTCYR      = 0x10, /* Year */
++      PCF50606_REG_RTCSCA     = 0x11, /* Alarm Second */
++      PCF50606_REG_RTCMNA     = 0x12, /* Alarm Minute */
++      PCF50606_REG_RTCHRA     = 0x13, /* Alarm Hour */
++      PCF50606_REG_RTCWDA     = 0x14, /* Alarm Weekday */
++      PCF50606_REG_RTCDTA     = 0x15, /* Alarm Day */
++      PCF50606_REG_RTCMTA     = 0x16, /* Alarm Month */
++      PCF50606_REG_RTCYRA     = 0x17, /* Alarm Year */
++      PCF50606_REG_PSSC       = 0x18, /* Power sequencing */
++      PCF50606_REG_PWROKM     = 0x19, /* PWROK mask */
++      PCF50606_REG_PWROKS     = 0x1a, /* PWROK status */
++      PCF50606_REG_DCDC1      = 0x1b,
++      PCF50606_REG_DCDC2      = 0x1c,
++      PCF50606_REG_DCDC3      = 0x1d,
++      PCF50606_REG_DCDC4      = 0x1e,
++      PCF50606_REG_DCDEC1     = 0x1f,
++      PCF50606_REG_DCDEC2     = 0x20,
++      PCF50606_REG_DCUDC1     = 0x21,
++      PCF50606_REG_DCUDC2     = 0x22,
++      PCF50606_REG_IOREGC     = 0x23,
++      PCF50606_REG_D1REGC1    = 0x24,
++      PCF50606_REG_D2REGC1    = 0x25,
++      PCF50606_REG_D3REGC1    = 0x26,
++      PCF50606_REG_LPREGC1    = 0x27,
++      PCF50606_REG_LPREGC2    = 0x28,
++      PCF50606_REG_MBCC1      = 0x29,
++      PCF50606_REG_MBCC2      = 0x2a,
++      PCF50606_REG_MBCC3      = 0x2b,
++      PCF50606_REG_MBCS1      = 0x2c,
++      PCF50606_REG_BBCC       = 0x2d,
++      PCF50606_REG_ADCC1      = 0x2e,
++      PCF50606_REG_ADCC2      = 0x2f,
++      PCF50606_REG_ADCS1      = 0x30,
++      PCF50606_REG_ADCS2      = 0x31,
++      PCF50606_REG_ADCS3      = 0x32,
++      PCF50606_REG_ACDC1      = 0x33,
++      PCF50606_REG_BVMC       = 0x34,
++      PCF50606_REG_PWMC1      = 0x35,
++      PCF50606_REG_LEDC1      = 0x36,
++      PCF50606_REG_LEDC2      = 0x37,
++      PCF50606_REG_GPOC1      = 0x38,
++      PCF50606_REG_GPOC2      = 0x39,
++      PCF50606_REG_GPOC3      = 0x3a,
++      PCF50606_REG_GPOC4      = 0x3b,
++      PCF50606_REG_GPOC5      = 0x3c,
++      __NUM_PCF50606_REGS
++};
++
++enum pcf50606_reg_oocs {
++      PFC50606_OOCS_ONKEY     = 0x01,
++      PCF50606_OOCS_EXTON     = 0x02,
++      PCF50606_OOCS_PWROKRST  = 0x04,
++      PCF50606_OOCS_BATOK     = 0x08,
++      PCF50606_OOCS_BACKOK    = 0x10,
++      PCF50606_OOCS_CHGOK     = 0x20,
++      PCF50606_OOCS_TEMPOK    = 0x40,
++      PCF50606_OOCS_WDTEXP    = 0x80,
++};
++
++enum pcf50606_reg_oocc1 {
++      PCF50606_OOCC1_GOSTDBY  = 0x01,
++      PCF50606_OOCC1_TOTRST   = 0x02,
++      PCF50606_OOCC1_CLK32ON  = 0x04,
++      PCF50606_OOCC1_WDTRST   = 0x08,
++      PCF50606_OOCC1_RTCWAK   = 0x10,
++      PCF50606_OOCC1_CHGWAK   = 0x20,
++      PCF50606_OOCC1_EXTONWAK_HIGH    = 0x40,
++      PCF50606_OOCC1_EXTONWAK_LOW     = 0x80,
++      PCF50606_OOCC1_EXTONWAK_NO_WAKEUP = 0x3f,
++};
++
++enum pcf50606_reg_oocc2 {
++      PCF50606_OOCC2_ONKEYDB_NONE     = 0x00,
++      PCF50606_OOCC2_ONKEYDB_14ms     = 0x01,
++      PCF50606_OOCC2_ONKEYDB_62ms     = 0x02,
++      PCF50606_OOCC2_ONKEYDB_500ms    = 0x03,
++      PCF50606_OOCC2_EXTONDB_NONE     = 0x00,
++      PCF50606_OOCC2_EXTONDB_14ms     = 0x04,
++      PCF50606_OOCC2_EXTONDB_62ms     = 0x08,
++      PCF50606_OOCC2_EXTONDB_500ms    = 0x0c,
++};
++
++enum pcf50606_reg_int1 {
++      PCF50606_INT1_ONKEYR    = 0x01, /* ONKEY rising edge */
++      PCF50606_INT1_ONKEYF    = 0x02, /* ONKEY falling edge */
++      PCF50606_INT1_ONKEY1S   = 0x04, /* OMKEY at least 1sec low */
++      PCF50606_INT1_EXTONR    = 0x08, /* EXTON rising edge */
++      PCF50606_INT1_EXTONF    = 0x10, /* EXTON falling edge */
++      PCF50606_INT1_SECOND    = 0x40, /* RTC periodic second interrupt */
++      PCF50606_INT1_ALARM     = 0x80, /* RTC alarm time is reached */
++};
++
++enum pcf50606_reg_int2 {
++      PCF50606_INT2_CHGINS    = 0x01, /* Charger inserted */
++      PCF50606_INT2_CHGRM     = 0x02, /* Charger removed */
++      PCF50606_INT2_CHGFOK    = 0x04, /* Fast charging OK */
++      PCF50606_INT2_CHGERR    = 0x08, /* Error in charging mode */
++      PCF50606_INT2_CHGFRDY   = 0x10, /* Fast charge completed */
++      PCF50606_INT2_CHGPROT   = 0x20, /* Charging protection interrupt */
++      PCF50606_INT2_CHGWD10S  = 0x40, /* Charger watchdig expires in 10s */
++      PCF50606_INT2_CHGWDEXP  = 0x80, /* Charger watchdog expires */
++};
++
++enum pcf50606_reg_int3 {
++      PCF50606_INT3_ADCRDY    = 0x01, /* ADC conversion finished */
++      PCF50606_INT3_ACDINS    = 0x02, /* Accessory inserted */
++      PCF50606_INT3_ACDREM    = 0x04, /* Accessory removed */
++      PCF50606_INT3_TSCPRES   = 0x08, /* Touch screen pressed */
++      PCF50606_INT3_LOWBAT    = 0x40, /* Low battery voltage */
++      PCF50606_INT3_HIGHTMP   = 0x80, /* High temperature */
++};
++
++/* used by PSSC, PWROKM, PWROKS, */
++enum pcf50606_regu {
++      PCF50606_REGU_DCD       = 0x01, /* DCD in phase 2 */
++      PCF50606_REGU_DCDE      = 0x02, /* DCDE in phase 2 */
++      PCF50606_REGU_DCUD      = 0x04, /* DCDU in phase 2 */
++      PCF50606_REGU_IO        = 0x08, /* IO in phase 2 */
++      PCF50606_REGU_D1        = 0x10, /* D1 in phase 2 */
++      PCF50606_REGU_D2        = 0x20, /* D2 in phase 2 */
++      PCF50606_REGU_D3        = 0x40, /* D3 in phase 2 */
++      PCF50606_REGU_LP        = 0x80, /* LP in phase 2 */
++};
++
++enum pcf50606_reg_dcdc4 {
++      PCF50606_DCDC4_MODE_AUTO        = 0x00,
++      PCF50606_DCDC4_MODE_PWM         = 0x01,
++      PCF50606_DCDC4_MODE_PCF         = 0x02,
++      PCF50606_DCDC4_OFF_FLOAT        = 0x00,
++      PCF50606_DCDC4_OFF_BYPASS       = 0x04,
++      PCF50606_DCDC4_OFF_PULLDOWN     = 0x08,
++      PCF50606_DCDC4_CURLIM_500mA     = 0x00,
++      PCF50606_DCDC4_CURLIM_750mA     = 0x10,
++      PCF50606_DCDC4_CURLIM_1000mA    = 0x20,
++      PCF50606_DCDC4_CURLIM_1250mA    = 0x30,
++      PCF50606_DCDC4_TOGGLE           = 0x40,
++      PCF50606_DCDC4_REGSEL_DCDC2     = 0x80,
++};
++
++enum pcf50606_reg_dcdec2 {
++      PCF50606_DCDEC2_MODE_AUTO       = 0x00,
++      PCF50606_DCDEC2_MODE_PWM        = 0x01,
++      PCF50606_DCDEC2_MODE_PCF        = 0x02,
++      PCF50606_DCDEC2_OFF_FLOAT       = 0x00,
++      PCF50606_DCDEC2_OFF_BYPASS      = 0x04,
++};
++
++enum pcf50606_reg_dcudc2 {
++      PCF50606_DCUDC2_MODE_AUTO       = 0x00,
++      PCF50606_DCUDC2_MODE_PWM        = 0x01,
++      PCF50606_DCUDC2_MODE_PCF        = 0x02,
++      PCF50606_DCUDC2_OFF_FLOAT       = 0x00,
++      PCF50606_DCUDC2_OFF_BYPASS      = 0x04,
++};
++
++enum pcf50606_reg_adcc1 {
++      PCF50606_ADCC1_TSCMODACT        = 0x01,
++      PCF50606_ADCC1_TSCMODSTB        = 0x02,
++      PCF50606_ADCC1_TRATSET          = 0x04,
++      PCF50606_ADCC1_NTCSWAPE         = 0x08,
++      PCF50606_ADCC1_NTCSWAOFF        = 0x10,
++      PCF50606_ADCC1_EXTSYNCBREAK     = 0x20,
++      /* reserved */
++      PCF50606_ADCC1_TSCINT           = 0x80,
++};
++
++enum pcf50606_reg_adcc2 {
++      PCF50606_ADCC2_ADCSTART         = 0x01,
++      /* see enum pcf50606_adcc2_adcmux */
++      PCF50606_ADCC2_SYNC_NONE        = 0x00,
++      PCF50606_ADCC2_SYNC_TXON        = 0x20,
++      PCF50606_ADCC2_SYNC_PWREN1      = 0x40,
++      PCF50606_ADCC2_SYNC_PWREN2      = 0x60,
++      PCF50606_ADCC2_RES_10BIT        = 0x00,
++      PCF50606_ADCC2_RES_8BIT         = 0x80,
++};
++
++#define PCF50606_ADCC2_ADCMUX_MASK    (0xf << 1)
++
++#define ADCMUX_SHIFT  1
++enum pcf50606_adcc2_adcmux {
++      PCF50606_ADCMUX_BATVOLT_RES     = 0x0 << ADCMUX_SHIFT,
++      PCF50606_ADCMUX_BATVOLT_SUBTR   = 0x1 << ADCMUX_SHIFT,
++      PCF50606_ADCMUX_ADCIN1_RES      = 0x2 << ADCMUX_SHIFT,
++      PCF50606_ADCMUX_ADCIN1_SUBTR    = 0x3 << ADCMUX_SHIFT,
++      PCF50606_ADCMUX_BATTEMP         = 0x4 << ADCMUX_SHIFT,
++      PCF50606_ADCMUX_ADCIN2          = 0x5 << ADCMUX_SHIFT,
++      PCF50606_ADCMUX_ADCIN3          = 0x6 << ADCMUX_SHIFT,
++      PCF50606_ADCMUX_ADCIN3_RATIO    = 0x7 << ADCMUX_SHIFT,
++      PCF50606_ADCMUX_XPOS            = 0x8 << ADCMUX_SHIFT,
++      PCF50606_ADCMUX_YPOS            = 0x9 << ADCMUX_SHIFT,
++      PCF50606_ADCMUX_P1              = 0xa << ADCMUX_SHIFT,
++      PCF50606_ADCMUX_P2              = 0xb << ADCMUX_SHIFT,
++      PCF50606_ADCMUX_BATVOLT_ADCIN1  = 0xc << ADCMUX_SHIFT,
++      PCF50606_ADCMUX_XY_SEQUENCE     = 0xe << ADCMUX_SHIFT,
++      PCF50606_P1_P2_RESISTANCE       = 0xf << ADCMUX_SHIFT,
++};
++
++enum pcf50606_adcs2 {
++      PCF50606_ADCS2_ADCRDY           = 0x80,
++};
++
++enum pcf50606_reg_mbcc1 {
++      PCF50606_MBCC1_CHGAPE           = 0x01,
++      PCF50606_MBCC1_AUTOFST          = 0x02,
++#define       PCF50606_MBCC1_CHGMOD_MASK        0x1c
++#define       PCF50606_MBCC1_CHGMOD_SHIFT       2
++      PCF50606_MBCC1_CHGMOD_QUAL      = 0x00,
++      PCF50606_MBCC1_CHGMOD_PRE       = 0x04,
++      PCF50606_MBCC1_CHGMOD_TRICKLE   = 0x08,
++      PCF50606_MBCC1_CHGMOD_FAST_CCCV = 0x0c,
++      PCF50606_MBCC1_CHGMOD_FAST_NOCC = 0x10,
++      PCF50606_MBCC1_CHGMOD_FAST_NOCV = 0x14,
++      PCF50606_MBCC1_CHGMOD_FAST_SW   = 0x18,
++      PCF50606_MBCC1_CHGMOD_IDLE      = 0x1c,
++      PCF50606_MBCC1_DETMOD_LOWCHG    = 0x20,
++      PCF50606_MBCC1_DETMOD_WDRST     = 0x40,
++};
++
++enum pcf50606_reg_bvmc {
++      PCF50606_BVMC_LOWBAT            = 0x01,
++      PCF50606_BVMC_THRSHLD_NULL      = 0x00,
++      PCF50606_BVMC_THRSHLD_2V8       = 0x02,
++      PCF50606_BVMC_THRSHLD_2V9       = 0x04,
++      PCF50606_BVMC_THRSHLD_3V        = 0x08,
++      PCF50606_BVMC_THRSHLD_3V1       = 0x08,
++      PCF50606_BVMC_THRSHLD_3V2       = 0x0a,
++      PCF50606_BVMC_THRSHLD_3V3       = 0x0c,
++      PCF50606_BVMC_THRSHLD_3V4       = 0x0e,
++      PCF50606_BVMC_DISDB             = 0x10,
++};
++
++/* this is to be provided by the board implementation */
++extern const u_int8_t pcf50606_initial_regs[__NUM_PCF50606_REGS];
++
++void pcf50606_reg_write(u_int8_t reg, u_int8_t val);
++
++u_int8_t pcf50606_reg_read(u_int8_t reg);
++
++void pcf50606_reg_set_bit_mask(u_int8_t reg, u_int8_t mask, u_int8_t val);
++void pcf50606_reg_clear_bits(u_int8_t reg, u_int8_t bits);
++
++void pcf50606_init(void);
++void pcf50606_charge_autofast(int on);
++
++#endif /* _PCF50606_H */
++
+Index: u-boot/board/neo1973/common/cmd_neo1973.c
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/common/cmd_neo1973.c
+@@ -0,0 +1,99 @@
++/*
++ * (C) Copyright 2006 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * 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
++ */
++
++/*
++ * Boot support
++ */
++#include <common.h>
++#include <command.h>
++#include <net.h>              /* for print_IPaddr */
++#include <s3c2410.h>
++
++#include "neo1973.h"
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#if (CONFIG_COMMANDS & CFG_CMD_BDI)
++
++int do_neo1973 ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++      int i;
++
++      if (!strcmp(argv[1], "info")) {
++              printf("FIC Neo1973 Hardware Revision 0x%04x\n", get_board_rev());
++      } else if (!strcmp(argv[1], "power-off")) {
++              neo1973_poweroff();
++      } else if (!strcmp(argv[1], "charger") || !strcmp(argv[1], "charge")) {
++              if (argc < 3)
++                      goto out_help;
++              if (!strcmp(argv[2], "status") || !strcmp(argv[2], "state")) {
++                      printf("%s\n", neo1973_get_charge_status());
++              } else if (!strcmp(argv[2], "autofast")) {
++                      neo1973_set_charge_mode(NEO1973_CHGCMD_AUTOFAST);
++              } else if (!strcmp(argv[2], "!autofast")) {
++                      neo1973_set_charge_mode(NEO1973_CHGCMD_NO_AUTOFAST);
++              } else if (!strcmp(argv[2], "off")) {
++                      neo1973_set_charge_mode(NEO1973_CHGCMD_OFF);
++              } else if (!strcmp(argv[2], "fast")) {
++                      neo1973_set_charge_mode(NEO1973_CHGCMD_FAST);
++              } else
++                      goto out_help;
++      } else if (!strcmp(argv[1], "backlight")) {
++              if (argc < 3)
++                      goto out_help;
++              if (!strcmp(argv[2], "on"))
++                      neo1973_backlight(1);
++              else
++                      neo1973_backlight(0);
++      } else if (!strcmp(argv[1], "vibrator")) {
++              if (argc < 3)
++                      goto out_help;
++              if (!strcmp(argv[2], "on"))
++                      neo1973_vibrator(1);
++              else
++                      neo1973_vibrator(0);
++      } else {
++out_help:
++              printf("Usage:\n%s\n", cmdtp->usage);
++              return 1;
++      }
++
++      return 0;
++}
++
++/* -------------------------------------------------------------------- */
++
++U_BOOT_CMD(
++      neo1973,        4,      1,      do_neo1973,
++      "neo1973 - phone specific commands\n",
++      "neo1973 info - display phone informantion\n"
++      "neo1973 power-off - switch off the phone\n"
++      "neo1973 charger status - display charger status\n"
++      "neo1973 charger autofast - enable automatic fast (500mA) charging\n"
++      "neo1973 charger !autofast - disable automatic fast (500mA) charging\n"
++      "neo1973 charger fast - enable fast (500mA) charging\n"
++      "neo1973 charger off - disable charging\n"
++      "neo1973 backlight (on|off) - switch backlight on or off\n"
++      "neo1973 vibrator (on|off) - switch vibrator on or off\n"
++);
++#endif        /* CFG_CMD_BDI */
+Index: u-boot/board/neo1973/common/jbt6k74.c
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/common/jbt6k74.c
+@@ -0,0 +1,420 @@
++/* u-boot driver for the tpo JBT6K74-AS LCM ASIC
++ *
++ * Copyright (C) 2006-2007 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ * All rights reserved.
++ *
++ * 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 <spi.h>
++#include <video_fb.h>
++#include <asm/errno.h>
++#include <s3c2410.h>
++#include "jbt6k74.h"
++
++#if 0
++#define DEBUGP(x, args...) printf("%s: " x, __FUNCTION__, ## args);
++#define DEBUGPC(x, args...) printf(x, ## args);
++#else
++#define DEBUGP(x, args...) do { } while (0)
++#define DEBUGPC(x, args...) do { } while (0)
++#endif
++
++
++enum jbt_register {
++      JBT_REG_SLEEP_IN                = 0x10,
++      JBT_REG_SLEEP_OUT               = 0x11,
++
++      JBT_REG_DISPLAY_OFF             = 0x28,
++      JBT_REG_DISPLAY_ON              = 0x29,
++
++      JBT_REG_RGB_FORMAT              = 0x3a,
++      JBT_REG_QUAD_RATE               = 0x3b,
++
++      JBT_REG_POWER_ON_OFF            = 0xb0,
++      JBT_REG_BOOSTER_OP              = 0xb1,
++      JBT_REG_BOOSTER_MODE            = 0xb2,
++      JBT_REG_BOOSTER_FREQ            = 0xb3,
++      JBT_REG_OPAMP_SYSCLK            = 0xb4,
++      JBT_REG_VSC_VOLTAGE             = 0xb5,
++      JBT_REG_VCOM_VOLTAGE            = 0xb6,
++      JBT_REG_EXT_DISPL               = 0xb7,
++      JBT_REG_OUTPUT_CONTROL          = 0xb8,
++      JBT_REG_DCCLK_DCEV              = 0xb9,
++      JBT_REG_DISPLAY_MODE1           = 0xba,
++      JBT_REG_DISPLAY_MODE2           = 0xbb,
++      JBT_REG_DISPLAY_MODE            = 0xbc,
++      JBT_REG_ASW_SLEW                = 0xbd,
++      JBT_REG_DUMMY_DISPLAY           = 0xbe,
++      JBT_REG_DRIVE_SYSTEM            = 0xbf,
++
++      JBT_REG_SLEEP_OUT_FR_A          = 0xc0,
++      JBT_REG_SLEEP_OUT_FR_B          = 0xc1,
++      JBT_REG_SLEEP_OUT_FR_C          = 0xc2,
++      JBT_REG_SLEEP_IN_LCCNT_D        = 0xc3,
++      JBT_REG_SLEEP_IN_LCCNT_E        = 0xc4,
++      JBT_REG_SLEEP_IN_LCCNT_F        = 0xc5,
++      JBT_REG_SLEEP_IN_LCCNT_G        = 0xc6,
++
++      JBT_REG_GAMMA1_FINE_1           = 0xc7,
++      JBT_REG_GAMMA1_FINE_2           = 0xc8,
++      JBT_REG_GAMMA1_INCLINATION      = 0xc9,
++      JBT_REG_GAMMA1_BLUE_OFFSET      = 0xca,
++
++      JBT_REG_BLANK_CONTROL           = 0xcf,
++      JBT_REG_BLANK_TH_TV             = 0xd0,
++      JBT_REG_CKV_ON_OFF              = 0xd1,
++      JBT_REG_CKV_1_2                 = 0xd2,
++      JBT_REG_OEV_TIMING              = 0xd3,
++      JBT_REG_ASW_TIMING_1            = 0xd4,
++      JBT_REG_ASW_TIMING_2            = 0xd5,
++
++      JBT_REG_HCLOCK_VGA              = 0xec,
++      JBT_REG_HCLOCK_QVGA             = 0xed,
++
++};
++
++static const char *jbt_state_names[] = {
++      [JBT_STATE_DEEP_STANDBY]        = "deep-standby",
++      [JBT_STATE_SLEEP]               = "sleep",
++      [JBT_STATE_NORMAL]              = "normal",
++};
++
++#define GTA01_SCLK    (1 << 7)        /* GPG7 */
++#define GTA01_MOSI    (1 << 6)        /* GPG6 */
++#define GTA01_MISO    (1 << 5)        /* GPG5 */
++#define GTA01_CS      (1 << 3)        /* GPG3 */
++
++#define SPI_READ        ((immr->GPGDAT & GTA01_MISO) != 0)
++
++#define SPI_CS(bit)   if (bit) gpio->GPGDAT |= GTA01_CS; \
++                      else gpio->GPGDAT &= ~GTA01_CS
++
++#define SPI_SDA(bit)    if (bit) gpio->GPGDAT |=  GTA01_MOSI; \
++                      else    gpio->GPGDAT &= ~GTA01_MOSI
++
++#define SPI_SCL(bit)    if (bit) gpio->GPGDAT |=  GTA01_SCLK; \
++                      else    gpio->GPGDAT &= ~GTA01_SCLK
++
++/* 150uS minimum clock cycle, we have two of this plus our other
++ * instructions */
++#define SPI_DELAY     udelay(100)     /* 200uS */
++
++
++#define JBT_TX_BUF_SIZE
++struct jbt_info {
++      enum jbt_state state;
++      u_int16_t tx_buf[4];
++      struct spi_device *spi_dev;
++};
++
++static struct jbt_info _jbt, *jbt = &_jbt;
++
++static int jbt_spi_xfer(int wordnum, int bitlen, u_int16_t *dout)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++      u_int16_t tmpdout = 0;
++      int   i, j;
++
++      DEBUGP("spi_xfer: dout %08X wordnum %u bitlen %d\n",
++              *(uint *)dout, wordnum, bitlen);
++
++      SPI_CS(0);
++
++      for (i = 0; i < wordnum; i ++) {
++              tmpdout = dout[i];
++
++              for (j = 0; j < bitlen; j++) {
++                      SPI_SCL(0);
++                      if (tmpdout & (1 << bitlen-1)) {
++                              SPI_SDA(1);
++                              DEBUGPC("1");
++                      } else {
++                              SPI_SDA(0);
++                              DEBUGPC("0");
++                      }
++                      SPI_DELAY;
++                      SPI_SCL(1);
++                      SPI_DELAY;
++                      tmpdout <<= 1;
++              }
++              DEBUGPC(" ");
++      }
++      DEBUGPC("\n");
++
++      SPI_CS(1);
++
++      return 0;
++}
++
++#define JBT_COMMAND   0x000
++#define JBT_DATA      0x100
++
++static int jbt_reg_write_nodata(struct jbt_info *jbt, u_int8_t reg)
++{
++      int rc;
++
++      jbt->tx_buf[0] = JBT_COMMAND | reg;
++
++      rc = jbt_spi_xfer(1, 9, jbt->tx_buf);
++
++      return rc;
++}
++
++
++static int jbt_reg_write(struct jbt_info *jbt, u_int8_t reg, u_int8_t data)
++{
++      int rc;
++
++      jbt->tx_buf[0] = JBT_COMMAND | reg;
++      jbt->tx_buf[1] = JBT_DATA | data;
++
++      rc = jbt_spi_xfer(2, 9, jbt->tx_buf);
++
++      return rc;
++}
++
++static int jbt_reg_write16(struct jbt_info *jbt, u_int8_t reg, u_int16_t data)
++{
++      int rc;
++
++      jbt->tx_buf[0] = JBT_COMMAND | reg;
++      jbt->tx_buf[1] = JBT_DATA | (data >> 8);
++      jbt->tx_buf[2] = JBT_DATA | (data & 0xff);
++
++      rc = jbt_spi_xfer(3, 9, jbt->tx_buf);
++
++      return rc;
++}
++
++static int jbt_init_regs(struct jbt_info *jbt)
++{
++      int rc;
++
++      DEBUGP("entering\n");
++
++      rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE1, 0x01);
++      rc |= jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE2, 0x00);
++      rc |= jbt_reg_write(jbt, JBT_REG_RGB_FORMAT, 0x60);
++      rc |= jbt_reg_write(jbt, JBT_REG_DRIVE_SYSTEM, 0x10);
++      rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_OP, 0x56);
++      rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_MODE, 0x33);
++      rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_FREQ, 0x11);
++      rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_FREQ, 0x11);
++      rc |= jbt_reg_write(jbt, JBT_REG_OPAMP_SYSCLK, 0x02);
++      rc |= jbt_reg_write(jbt, JBT_REG_VSC_VOLTAGE, 0x2b);
++      rc |= jbt_reg_write(jbt, JBT_REG_VCOM_VOLTAGE, 0x40);
++      rc |= jbt_reg_write(jbt, JBT_REG_EXT_DISPL, 0x03);
++      rc |= jbt_reg_write(jbt, JBT_REG_DCCLK_DCEV, 0x04);
++      rc |= jbt_reg_write(jbt, JBT_REG_ASW_SLEW, 0x02);
++      rc |= jbt_reg_write(jbt, JBT_REG_DUMMY_DISPLAY, 0x00);
++
++      rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_A, 0x11);
++      rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_B, 0x11);
++      rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_C, 0x11);
++      rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_D, 0x2040);
++      rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_E, 0x60c0);
++      rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_F, 0x1020);
++      rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_G, 0x60c0);
++
++      rc |= jbt_reg_write16(jbt, JBT_REG_GAMMA1_FINE_1, 0x5533);
++      rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_FINE_2, 0x00);
++      rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_INCLINATION, 0x00);
++      rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_BLUE_OFFSET, 0x00);
++      rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_BLUE_OFFSET, 0x00);
++
++      rc |= jbt_reg_write16(jbt, JBT_REG_HCLOCK_VGA, 0x1f0);
++      rc |= jbt_reg_write(jbt, JBT_REG_BLANK_CONTROL, 0x02);
++      rc |= jbt_reg_write16(jbt, JBT_REG_BLANK_TH_TV, 0x0804);
++      rc |= jbt_reg_write16(jbt, JBT_REG_BLANK_TH_TV, 0x0804);
++
++      rc |= jbt_reg_write(jbt, JBT_REG_CKV_ON_OFF, 0x01);
++      rc |= jbt_reg_write16(jbt, JBT_REG_CKV_1_2, 0x0000);
++
++      rc |= jbt_reg_write16(jbt, JBT_REG_OEV_TIMING, 0x0d0e);
++      rc |= jbt_reg_write16(jbt, JBT_REG_ASW_TIMING_1, 0x11a4);
++      rc |= jbt_reg_write(jbt, JBT_REG_ASW_TIMING_2, 0x0e);
++
++#if 0
++      rc |= jbt_reg_write16(jbt, JBT_REG_HCLOCK_QVGA, 0x00ff);
++      rc |= jbt_reg_write16(jbt, JBT_REG_HCLOCK_QVGA, 0x00ff);
++#endif
++
++      return rc;
++}
++
++static int standby_to_sleep(struct jbt_info *jbt)
++{
++      int rc;
++
++      DEBUGP("entering\n");
++
++      /* three times command zero */
++      rc = jbt_reg_write_nodata(jbt, 0x00);
++      udelay(1000);
++      rc = jbt_reg_write_nodata(jbt, 0x00);
++      udelay(1000);
++      rc = jbt_reg_write_nodata(jbt, 0x00);
++      udelay(1000);
++
++      /* deep standby out */
++      rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x17);
++
++      return rc;
++}
++
++static int sleep_to_normal(struct jbt_info *jbt)
++{
++      int rc;
++      DEBUGP("entering\n");
++
++      /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */
++      rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x80);
++
++      /* Quad mode off */
++      rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x00);
++
++      /* AVDD on, XVDD on */
++      rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x16);
++
++      /* Output control */
++      rc |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0xfff9);
++
++      /* Sleep mode off */
++      rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_OUT);
++
++      /* initialize register set */
++      rc |= jbt_init_regs(jbt);
++      return rc;
++}
++
++static int normal_to_sleep(struct jbt_info *jbt)
++{
++      int rc;
++      DEBUGP("entering\n");
++
++      rc = jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_OFF);
++      rc |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0x8002);
++      rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_IN);
++
++      return rc;
++}
++
++static int sleep_to_standby(struct jbt_info *jbt)
++{
++      DEBUGP("entering\n");
++      return jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x00);
++}
++
++/* frontend function */
++int jbt6k74_enter_state(enum jbt_state new_state)
++{
++      int rc = -EINVAL;
++
++      DEBUGP("entering(old_state=%u, new_state=%u)\n", jbt->state, new_state);
++
++      switch (jbt->state) {
++      case JBT_STATE_DEEP_STANDBY:
++              switch (new_state) {
++              case JBT_STATE_DEEP_STANDBY:
++                      rc = 0;
++                      break;
++              case JBT_STATE_SLEEP:
++                      rc = standby_to_sleep(jbt);
++                      break;
++              case JBT_STATE_NORMAL:
++                      /* first transition into sleep */
++                      rc = standby_to_sleep(jbt);
++                      /* then transition into normal */
++                      rc |= sleep_to_normal(jbt);
++                      break;
++              }
++              break;
++      case JBT_STATE_SLEEP:
++              switch (new_state) {
++              case JBT_STATE_SLEEP:
++                      rc = 0;
++                      break;
++              case JBT_STATE_DEEP_STANDBY:
++                      rc = sleep_to_standby(jbt);
++                      break;
++              case JBT_STATE_NORMAL:
++                      rc = sleep_to_normal(jbt);
++                      break;
++              }
++              break;
++      case JBT_STATE_NORMAL:
++              switch (new_state) {
++              case JBT_STATE_NORMAL:
++                      rc = 0;
++                      break;
++              case JBT_STATE_DEEP_STANDBY:
++                      /* first transition into sleep */
++                      rc = normal_to_sleep(jbt);
++                      /* then transition into deep standby */
++                      rc |= sleep_to_standby(jbt);
++                      break;
++              case JBT_STATE_SLEEP:
++                      rc = normal_to_sleep(jbt);
++                      break;
++              }
++              break;
++      }
++
++      return rc;
++}
++
++int jbt6k74_display_onoff(int on)
++{
++      DEBUGP("entering\n");
++      if (on)
++              return jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_ON);
++      else
++              return jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_OFF);
++}
++
++int jbt6k74_init(void)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++      /* initialize SPI for GPIO bitbang */
++      gpio->GPGCON &= 0xffff033f;
++      gpio->GPGCON |= 0x00005440;
++
++      /* get LCM out of reset */
++      gpio->GPCDAT |= (1 << 6);
++
++      /* according to data sheet: wait 50ms (Tpos of LCM). However, 50ms
++       * seems unreliable with later LCM batches, increasing to 90ms */
++      udelay(90000);
++
++      return 0;
++}
++
++void board_video_init(GraphicDevice *pGD)
++{
++      S3C24X0_LCD * const lcd = S3C24X0_GetBase_LCD();
++
++      lcd->LCDCON1 = 0x00000178; /* CLKVAL=1, BPPMODE=16bpp, TFT, ENVID=0 */
++
++      lcd->LCDCON2 = 0x019fc3c1;
++      lcd->LCDCON3 = 0x0039df67;
++      lcd->LCDCON4 = 0x00000007;
++      lcd->LCDCON5 = 0x0001cf09;
++      lcd->LPCSEL  = 0x00000000;
++}
+Index: u-boot/board/neo1973/common/jbt6k74.h
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/common/jbt6k74.h
+@@ -0,0 +1,14 @@
++#ifndef _JBT6K74_H
++#define _JBT6K74_H
++
++enum jbt_state {
++      JBT_STATE_DEEP_STANDBY,
++      JBT_STATE_SLEEP,
++      JBT_STATE_NORMAL,
++};
++
++int jbt6k74_init(void);
++int jbt6k74_display_onoff(int on);
++int jbt6k74_enter_state(enum jbt_state new_state);
++
++#endif
+Index: u-boot/board/neo1973/common/lowlevel_init.S
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/common/lowlevel_init.S
+@@ -0,0 +1,187 @@
++/*
++ * Memory Setup stuff - taken from blob memsetup.S
++ *
++ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
++ *                     Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
++ *
++ * Modified for the FIC Neo1973 GTA01 by Harald Welte <laforge@openmoko.org>
++ *
++ * 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 <version.h>
++
++
++/* some parameters for the board */
++
++/*
++ *
++ * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
++ *
++ * Copyright (C) 2002 Samsung Electronics SW.LEE  <hitchcar@sec.samsung.com>
++ *
++ */
++
++#define BWSCON        0x48000000
++
++/* BWSCON */
++#define DW8                   (0x0)
++#define DW16                  (0x1)
++#define DW32                  (0x2)
++#define WAIT                  (0x1<<2)
++#define UBLB                  (0x1<<3)
++
++#define B1_BWSCON             (DW32)
++#define B2_BWSCON             (DW16)
++#define B3_BWSCON             (DW16 + WAIT + UBLB)
++#define B4_BWSCON             (DW16)
++#define B5_BWSCON             (DW16)
++#define B6_BWSCON             (DW32)
++#define B7_BWSCON             (DW32)
++
++/* BANK0CON */
++#define B0_Tacs                       0x0     /*  0clk */
++#define B0_Tcos                       0x0     /*  0clk */
++#define B0_Tacc                       0x7     /* 14clk */
++#define B0_Tcoh                       0x0     /*  0clk */
++#define B0_Tah                        0x0     /*  0clk */
++#define B0_Tacp                       0x0
++#define B0_PMC                        0x0     /* normal */
++
++/* BANK1CON */
++#define B1_Tacs                       0x0     /*  0clk */
++#define B1_Tcos                       0x0     /*  0clk */
++#define B1_Tacc                       0x7     /* 14clk */
++#define B1_Tcoh                       0x0     /*  0clk */
++#define B1_Tah                        0x0     /*  0clk */
++#define B1_Tacp                       0x0
++#define B1_PMC                        0x0
++
++#define B2_Tacs                       0x0
++#define B2_Tcos                       0x0
++#define B2_Tacc                       0x7
++#define B2_Tcoh                       0x0
++#define B2_Tah                        0x0
++#define B2_Tacp                       0x0
++#define B2_PMC                        0x0
++
++#define B3_Tacs                       0x0     /*  0clk */
++#define B3_Tcos                       0x3     /*  4clk */
++#define B3_Tacc                       0x7     /* 14clk */
++#define B3_Tcoh                       0x1     /*  1clk */
++#define B3_Tah                        0x0     /*  0clk */
++#define B3_Tacp                       0x3     /*  6clk */
++#define B3_PMC                        0x0     /* normal */
++
++#define B4_Tacs                       0x0     /*  0clk */
++#define B4_Tcos                       0x0     /*  0clk */
++#define B4_Tacc                       0x7     /* 14clk */
++#define B4_Tcoh                       0x0     /*  0clk */
++#define B4_Tah                        0x0     /*  0clk */
++#define B4_Tacp                       0x0
++#define B4_PMC                        0x0     /* normal */
++
++#define B5_Tacs                       0x0     /*  0clk */
++#define B5_Tcos                       0x0     /*  0clk */
++#define B5_Tacc                       0x7     /* 14clk */
++#define B5_Tcoh                       0x0     /*  0clk */
++#define B5_Tah                        0x0     /*  0clk */
++#define B5_Tacp                       0x0
++#define B5_PMC                        0x0     /* normal */
++
++#define B6_MT                 0x3     /* SDRAM */
++#define B6_Trcd                       0x1     /* 3clk */
++#if defined (CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
++#define B6_SCAN                       0x1     /* 9bit */
++#elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3) || \
++      defined(CONFIG_ARCH_GTA01B_v4)
++#define B6_SCAN                       0x2     /* 10bit */
++#endif
++
++#define B7_MT                 0x3     /* SDRAM */
++#define B7_Trcd                       0x1     /* 3clk */
++#define B7_SCAN                       0x2     /* 10bit */
++
++/* REFRESH parameter */
++#define REFEN                 0x1     /* Refresh enable */
++#define TREFMD                        0x0     /* CBR(CAS before RAS)/Auto refresh */
++#define Trp                   0x1     /* 3clk */
++#define Trc                   0x3     /* 7clk */
++#define Tchr                  0x2     /* 3clk */
++//#define REFCNT                      1113    /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
++#define REFCNT                        997     /* period=17.5us, HCLK=60Mhz, (2048+1-15.6*60) */
++/**************************************/
++
++_TEXT_BASE:
++      .word   TEXT_BASE
++
++.globl lowlevel_init
++lowlevel_init:
++      /* memory control configuration */
++      /* make r0 relative the current location so that it */
++      /* reads SMRDATA out of FLASH rather than memory ! */
++      adr     r0, SMRDATA
++      ldr     r1, =BWSCON     /* Bus Width Status Controller */
++      add     r2, r0, #13*4
++0:
++      ldr     r3, [r0], #4
++      str     r3, [r1], #4
++      cmp     r2, r0
++      bne     0b
++
++      /* setup asynchronous bus mode */
++      mrc     p15, 0, r1 ,c1 ,c0, 0
++      orr     r1, r1, #0xc0000000
++      mcr     p15, 0, r1, c1, c0, 0
++
++#if defined(CONFIG_ARCH_GTA01_v4) || defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
++      /* switch on power for NAND */
++      ldr     r0, =0x56000010 /* GPBCON */
++      ldr     r1, [r0]
++      orr     r1, r1, #0x10
++      str     r1, [r0]
++
++      ldr     r0, =0x56000014 /* GPBDAT */
++      ldr     r1, [r0]
++      orr     r1, r1, #(1 <<2)
++      str     r1, [r0]
++#endif
++
++      /* everything is fine now */
++      mov     pc, lr
++
++      .ltorg
++/* the literal pools origin */
++
++SMRDATA:
++    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
++    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
++    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
++    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
++    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
++    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
++    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
++    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
++    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
++    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
++    .word 0xb2
++    .word 0x30
++    .word 0x30
+Index: u-boot/board/neo1973/gta01/Makefile
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/gta01/Makefile
+@@ -0,0 +1,47 @@
++#
++# (C) Copyright 2000, 2001, 2002
++# Wolfgang Denk, DENX Software Engineering, wd@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
++#
++
++include $(TOPDIR)/config.mk
++
++LIB   = lib$(BOARD).a
++
++OBJS  := gta01.o pcf50606.o ../common/cmd_neo1973.o ../common/jbt6k74.o
++SOBJS := ../common/lowlevel_init.o
++
++$(LIB):       $(OBJS) $(SOBJS)
++      $(AR) crv $@ $(OBJS) $(SOBJS)
++
++clean:
++      rm -f $(SOBJS) $(OBJS)
++
++distclean:    clean
++      rm -f $(LIB) core *.bak .depend
++
++#########################################################################
++
++.depend:      Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
++              $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
++
++-include .depend
++
++#########################################################################
+Index: u-boot/board/neo1973/gta01/config.mk
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/gta01/config.mk
+@@ -0,0 +1,34 @@
++#
++# (C) Copyright 2002
++# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
++# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++#
++# FIC Neo1973 GTA01 board with S3C2410X (ARM920T) cpu
++#
++# see http://www.samsung.com/ for more information on SAMSUNG
++#
++
++# GTA01v3 has 1 bank of 64 MB SDRAM
++# GTA01v4 has 1 bank of 64 MB SDRAM
++#
++#     3000'0000 to 3400'0000
++# we load ourself to 33F8'0000
++#
++# GTA01Bv2 or later has 1 bank of 128 MB SDRAM
++#
++#     3000'0000 to 3800'0000
++# we load ourself to 37F8'0000
++#
++# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
++# optionally with a ramdisk at 3080'0000
++#
++# download area is 3200'0000 or 3300'0000
++
++sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
++
++ifeq ($(GTA01_BIG_RAM),y)
++# FIXME: TEXT_BASE = 0x37F80000
++TEXT_BASE = 0x33F80000
++else
++TEXT_BASE = 0x33F80000
++endif
+Index: u-boot/board/neo1973/gta01/gta01.c
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/gta01/gta01.c
+@@ -0,0 +1,422 @@
++/*
++ * (C) 2006 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * based on existing S3C2410 startup code in u-boot:
++ *
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Marius Groeger <mgroeger@sysgo.de>
++ *
++ * (C) Copyright 2002
++ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++ *
++ * 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 <s3c2410.h>
++#include <i2c.h>
++
++#include "pcf50606.h"
++
++#include "../common/neo1973.h"
++#include "../common/jbt6k74.h"
++
++DECLARE_GLOBAL_DATA_PTR;
++
++/* That many seconds the power key needs to be pressed to power up */
++#define POWER_KEY_SECONDS     2
++
++#if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
++//#define M_MDIV      0xA1            /* Fout = 202.8MHz */
++//#define M_PDIV      0x3
++//#define M_SDIV      0x1
++#define M_MDIV        0x90            /* Fout = 202.8MHz */
++#define M_PDIV        0x7
++#define M_SDIV        0x0
++#elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
++/* In case the debug board is attached, we cannot go beyond 200 MHz */
++#if 0
++#define M_MDIV        0x7d            /* Fout = 266MHz */
++#define M_PDIV        0x1
++#define M_SDIV        0x1
++#else
++#define M_MDIV        0x90            /* Fout = 202.8MHz */
++#define M_PDIV        0x7
++#define M_SDIV        0x0
++#endif
++#elif defined(CONFIG_ARCH_GTA01B_v4)
++/* This board doesn't have bus lines at teh debug port, and we can go to 266 */
++#define M_MDIV        0x7d            /* Fout = 266MHz */
++#define M_PDIV        0x1
++#define M_SDIV        0x1
++#else
++#error Please define GTA01 revision
++#endif
++
++#define U_M_MDIV      0x78
++#define U_M_PDIV      0x2
++#define U_M_SDIV      0x3
++
++unsigned int neo1973_wakeup_cause;
++extern int nobootdelay;
++
++static inline void delay (unsigned long loops)
++{
++      __asm__ volatile ("1:\n"
++        "subs %0, %1, #1\n"
++        "bne 1b":"=r" (loops):"0" (loops));
++}
++
++/*
++ * Miscellaneous platform dependent initialisations
++ */
++
++int board_init (void)
++{
++      S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++      /* to reduce PLL lock time, adjust the LOCKTIME register */
++      clk_power->LOCKTIME = 0xFFFFFF;
++
++      /* configure MPLL */
++      clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
++
++      /* some delay between MPLL and UPLL */
++      delay (4000);
++
++      /* configure UPLL */
++      clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
++
++      /* some delay between MPLL and UPLL */
++      delay (8000);
++
++      /* set up the I/O ports */
++#if defined(CONFIG_ARCH_GTA01_v3)
++      gpio->GPACON = 0x007FFFFF;
++
++      gpio->GPBCON = 0x00005055;
++      gpio->GPBUP = 0x000007FF;
++
++      gpio->GPCCON = 0xAAAA12A8;
++      gpio->GPCUP = 0x0000FFFF;
++
++      gpio->GPDCON = 0xAAAAAAAA;
++      gpio->GPDUP = 0x0000FFFF;
++
++      gpio->GPECON = 0xAAAAAAAA;
++      gpio->GPEUP = 0x0000FFFF;
++
++      gpio->GPFCON = 0x00002AA9;
++      gpio->GPFUP = 0x000000FF;
++
++      gpio->GPGCON = 0xA846F0C0;
++      gpio->GPGUP = 0x0000AFEF;
++
++      gpio->GPHCON = 0x0008FAAA;
++      gpio->GPHUP = 0x000007FF;
++#elif defined(CONFIG_ARCH_GTA01_v4)
++      gpio->GPACON = 0x005E47FF;
++
++      gpio->GPBCON = 0x00045015;
++      gpio->GPBUP = 0x000007FF;
++      gpio->GPBDAT |= 0x4;            /* Set GPB2 to high (Flash power-up) */
++
++      gpio->GPCCON = 0xAAAA12A9;
++      gpio->GPCUP = 0x0000FFFF;
++
++      gpio->GPDCON = 0xAAAAAAAA;
++      gpio->GPDUP = 0x0000FFFF;
++
++      gpio->GPECON = 0xA02AAAAA;
++      gpio->GPEUP = 0x0000FFFF;
++
++      gpio->GPFCON = 0x0000aa09;
++      gpio->GPFUP = 0x000000FF;
++
++      gpio->GPGCON = 0xFF40F0C1;
++      gpio->GPGUP = 0x0000AFEF;
++
++      gpio->GPHCON = 0x0000FAAA;
++      gpio->GPHUP = 0x000007FF;
++#elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
++      gpio->GPACON = 0x005E4FFF;
++
++      gpio->GPBCON = 0x00145415;
++      gpio->GPBUP = 0x000007FF;
++      gpio->GPBDAT |= 0x4;            /* Set GPB2 to high (Flash power-up) */
++
++      gpio->GPCCON = 0xAAAA12A9;
++      gpio->GPCUP = 0x0000FFFF;
++
++      gpio->GPDCON = 0xAAAAAAAA;
++      gpio->GPDUP = 0x0000FFFF;
++
++      gpio->GPECON = 0xA02AAAAA;
++      gpio->GPEUP = 0x0000FFFF;
++
++      gpio->GPFCON = 0x0000aa19;
++      gpio->GPFUP = 0x000000FF;
++      gpio->GPFDAT |= 0x4;            /* Set GBF2 to high (nGSM_EN) */
++
++      gpio->GPGCON = 0xFF40F0C1;
++      gpio->GPGUP = 0x0000AFEF;
++
++      gpio->GPHCON = 0x0000FAAA;
++      gpio->GPHUP = 0x000007FF;
++#elif defined(CONFIG_ARCH_GTA01B_v4)
++      gpio->GPACON = 0x0005E0FFF;
++      gpio->GPADAT |= (1 << 16);      /* Set GPA16 to high (nNAND_WP) */
++
++      gpio->GPBCON = 0x00045455;
++      gpio->GPBUP = 0x000007FF;
++      gpio->GPBDAT |= 0x4;            /* Set GPB2 to high (SD power down) */
++
++      gpio->GPCCON = 0xAAAA12A9;
++      gpio->GPCUP = 0x0000FFFF;
++
++      gpio->GPDCON = 0xAAAAAAAA;
++      gpio->GPDUP = 0x0000FFFF;
++
++      gpio->GPECON = 0xAAAAAAAA;
++      gpio->GPEUP = 0x0000FFFF;
++
++      gpio->GPFCON = 0x0000aa99;
++      gpio->GPFUP = 0x000000FF;
++      gpio->GPFDAT |= 0x4;            /* Set GBF2 to high (nGSM_EN) */
++
++      gpio->GPGCON = 0xFF14F0F8;
++      gpio->GPGUP = 0x0000AFEF;
++
++      gpio->GPHCON = 0x0000FAAA;
++      gpio->GPHUP = 0x000007FF;
++#else
++#error Please define GTA01 version
++#endif
++
++      /* arch number of SMDK2410-Board */
++      gd->bd->bi_arch_number = MACH_TYPE_NEO1973_GTA01;
++
++      /* adress of boot parameters */
++      gd->bd->bi_boot_params = 0x30000100;
++
++      icache_enable();
++      dcache_enable();
++
++      return 0;
++}
++
++int board_late_init(void)
++{
++      unsigned char tmp;
++      char buf[32];
++
++      /* Initialize the Power Management Unit with a safe register set */
++      pcf50606_init();
++
++      /* obtain wake-up reason, save INT1 in environment */
++      tmp = pcf50606_reg_read(PCF50606_REG_INT1);
++      sprintf(buf, "0x%02x", tmp);
++      setenv("pcf50606_int1", buf);
++
++      if (tmp & PCF50606_INT1_ALARM) {
++              /* we've been woken up by RTC alarm or charger insert, boot */
++              neo1973_wakeup_cause = NEO1973_WAKEUP_ALARM;
++              goto continue_boot;
++      }
++      if (tmp & PCF50606_INT1_EXTONR) {
++              neo1973_wakeup_cause = NEO1973_WAKEUP_CHARGER;
++      }
++
++      if (tmp & PCF50606_INT1_ONKEYF) {
++              int seconds = 0;
++              neo1973_wakeup_cause = NEO1973_WAKEUP_POWER_KEY;
++              /* we've been woken up by a falling edge of the onkey */
++
++              /* we can't just setenv(bootdelay,-1) because that would
++               * accidentially become permanent if the user does saveenv */
++              if (neo1973_911_key_pressed())
++                      nobootdelay = 1;
++
++              while (1) {
++                      u_int8_t int1, oocs;
++
++                      oocs = pcf50606_reg_read(PCF50606_REG_OOCS);
++                      if (oocs & PFC50606_OOCS_ONKEY)
++                              break;
++
++                      int1 = pcf50606_reg_read(PCF50606_REG_INT1);
++                      if (int1 & PCF50606_INT1_SECOND)
++                              seconds++;
++
++                      if (seconds >= POWER_KEY_SECONDS)
++                              goto continue_boot;
++              }
++              /* Power off if minimum number of seconds not reached */
++              neo1973_poweroff();
++      }
++
++      /* if there's no other reason, must be regular reset */
++      neo1973_wakeup_cause = NEO1973_WAKEUP_RESET;
++
++continue_boot:
++      jbt6k74_init();
++      jbt6k74_enter_state(JBT_STATE_NORMAL);
++      jbt6k74_display_onoff(1);
++
++      /* issue a short pulse with the vibrator */
++      neo1973_vibrator(1);
++      udelay(50000);
++      neo1973_vibrator(0);
++
++      /* switch on the backlight */
++      neo1973_backlight(1);
++
++#if defined(CONFIG_ARCH_GTA01B_v4)
++      {
++              /* check if sd card is inserted, and power-up if it is */
++              S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++              if (!(gpio->GPFDAT & (1 << 5)))
++                      gpio->GPBDAT &= ~(1 << 2);
++      }
++#endif
++
++      return 0;
++}
++
++int dram_init (void)
++{
++      gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
++      gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
++
++      return 0;
++}
++
++u_int32_t get_board_rev(void)
++{
++#if defined(CONFIG_ARCH_GTA01_v3)
++      return 0x00000130;
++#elif defined(CONFIG_ARCH_GTA01_v4)
++      return 0x00000140;
++#elif defined(CONFIG_ARCH_GTA01B_v2)
++      return 0x00000220;
++#elif defined(CONFIG_ARCH_GTA01B_v3)
++      return 0x00000230;
++#elif defined(CONFIG_ARCH_GTA01B_v4)
++      return 0x00000240;
++#endif
++}
++
++void neo1973_poweroff(void)
++{
++      serial_printf("poweroff\n");
++      udc_disconnect();
++      pcf50606_reg_write(PCF50606_REG_OOCC1, PCF50606_OOCC1_GOSTDBY);
++      /* don't return to caller */
++      while (1) ;
++}
++
++void neo1973_backlight(int on)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++      if (on)
++              gpio->GPBDAT |= 0x01;
++      else
++              gpio->GPBDAT &= ~0x01;
++}
++
++void neo1973_vibrator(int on)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++      if (on)
++#if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
++              gpio->GPGDAT |= (1 << 11);      /* GPG11 */
++#elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
++              gpio->GPBDAT |= (1 << 10);      /* GPB10 */
++#elif defined(CONFIG_ARCH_GTA01B_v4)
++              gpio->GPBDAT |= (1 << 3);       /* GPB3 */
++#endif
++      else
++#if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
++              gpio->GPGDAT &= ~(1 << 11);     /* GPG11 */
++#elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
++              gpio->GPBDAT &= ~(1 << 10);     /* GPB10 */
++#elif defined(CONFIG_ARCH_GTA01B_v4)
++              gpio->GPBDAT &= ~(1 << 3);      /* GPB3 */
++#endif
++}
++
++int neo1973_911_key_pressed(void)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++      if (gpio->GPFDAT & (1 << 6))
++              return 0;
++      return 1;
++}
++
++static const char *chgstate_names[] = {
++      [PCF50606_MBCC1_CHGMOD_QUAL]            = "qualification",
++      [PCF50606_MBCC1_CHGMOD_PRE]             = "pre",
++      [PCF50606_MBCC1_CHGMOD_TRICKLE]         = "trickle",
++      [PCF50606_MBCC1_CHGMOD_FAST_CCCV]       = "fast_cccv",
++      [PCF50606_MBCC1_CHGMOD_FAST_NOCC]       = "fast_nocc",
++      [PCF50606_MBCC1_CHGMOD_FAST_NOCV]       = "fast_nocv",
++      [PCF50606_MBCC1_CHGMOD_FAST_SW]         = "fast_switch",
++      [PCF50606_MBCC1_CHGMOD_IDLE]            = "idle",
++};
++
++const char *neo1973_get_charge_status(void)
++{
++      u_int8_t mbcc1 = pcf50606_reg_read(PCF50606_REG_MBCC1);
++      u_int8_t chgmod = (mbcc1 & PCF50606_MBCC1_CHGMOD_MASK);
++      return chgstate_names[chgmod];
++}
++
++int neo1973_set_charge_mode(enum neo1973_charger_cmd cmd)
++{
++      switch (cmd) {
++      case NEO1973_CHGCMD_NONE:
++              break;
++      case NEO1973_CHGCMD_AUTOFAST:
++              pcf50606_reg_set_bit_mask(PCF50606_REG_MBCC1,
++                                        PCF50606_MBCC1_AUTOFST,
++                                        PCF50606_MBCC1_AUTOFST);
++              break;
++      case NEO1973_CHGCMD_NO_AUTOFAST:
++              pcf50606_reg_set_bit_mask(PCF50606_REG_MBCC1,
++                                        PCF50606_MBCC1_AUTOFST, 0);
++              break;
++      case NEO1973_CHGCMD_OFF:
++              pcf50606_reg_set_bit_mask(PCF50606_REG_MBCC1,
++                                        PCF50606_MBCC1_CHGMOD_MASK,
++                                        PCF50606_MBCC1_CHGMOD_IDLE);
++              break;
++
++      case NEO1973_CHGCMD_FAST:
++      case NEO1973_CHGCMD_FASTER:
++              pcf50606_reg_set_bit_mask(PCF50606_REG_MBCC1,
++                                        PCF50606_MBCC1_CHGMOD_MASK,
++                                        PCF50606_MBCC1_CHGMOD_FAST_CCCV);
++              break;
++      }
++      return 0;
++}
++
+Index: u-boot/board/neo1973/gta01/pcf50606.c
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/gta01/pcf50606.c
+@@ -0,0 +1,100 @@
++
++#include <common.h>
++#include <pcf50606.h>
++
++/* initial register set for PCF50606 in Neo1973 devices */
++const u_int8_t pcf50606_initial_regs[__NUM_PCF50606_REGS] = {
++      [PCF50606_REG_OOCS]     = 0x00,
++      /* gap */
++      [PCF50606_REG_INT1M]    = PCF50606_INT1_SECOND,
++      [PCF50606_REG_INT2M]    = 0x00,
++      [PCF50606_REG_INT3M]    = PCF50606_INT3_TSCPRES,
++      [PCF50606_REG_OOCC1]    = PCF50606_OOCC1_RTCWAK |
++                                PCF50606_OOCC1_CHGWAK |
++                                PCF50606_OOCC1_EXTONWAK_HIGH,
++      [PCF50606_REG_OOCC2]    = PCF50606_OOCC2_ONKEYDB_14ms |
++                                PCF50606_OOCC2_EXTONDB_14ms,
++      /* gap */
++      [PCF50606_REG_PSSC]     = 0x00,
++      [PCF50606_REG_PWROKM]   = 0x00,
++      /* gap */
++#if defined(CONFIG_ARCH_GTA01B_v2)
++      [PCF50606_REG_DCDC1]    = 0x1e, /* GL_3V3: off */
++#elif defined(CONFIG_ARCH_GTA01B_v3) || defined(CONFIG_ARCH_GTA01B_v4)
++      [PCF50606_REG_DCDC1]    = 0x18, /* GL_1V5: off */
++#endif
++      [PCF50606_REG_DCDC2]    = 0x00,
++      [PCF50606_REG_DCDC3]    = 0x00,
++      [PCF50606_REG_DCDC4]    = 0x30, /* 1.25A */
++
++      [PCF50606_REG_DCDEC1]   = 0xe8, /* IO_3V3: on */
++      [PCF50606_REG_DCDEC2]   = 0x00,
++
++#if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
++      [PCF50606_REG_DCUDC1]   = 0xe3, /* CORE_1V8: 1.8V */
++#elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
++      [PCF50606_REG_DCUDC1]   = 0xe4, /* CORE_1V8: 2.1V */
++#elif defined(CONFIG_ARCH_GTA01B_v4)
++      [PCF50606_REG_DCUDC1]   = 0xc4, /* CORE_1V8: 2.1V if PWREN2 = HIGH */
++#endif
++      [PCF50606_REG_DCUDC2]   = 0x30, /* 1.25A current limit */
++
++#if defined(CONFIG_ARCH_GTA01_v3)
++      [PCF50606_REG_IOREGC]   = 0x13, /* VTCXO_2V8: off */
++#elif defined(CONFIG_ARCH_GTA01_v4) || defined(CONFIG_ARCH_GTA01B_v2) || \
++      defined(CONFIG_ARCH_GTA01B_v3) || defined(CONFIG_ARCH_GTA01B_v4)
++      //see internal bug 94 [PCF50606_REG_IOREGC]     = 0x18, /* CODEC_3V3: off */
++      [PCF50606_REG_IOREGC]   = 0xf8, /* CODEC_3V3: on */
++#endif
++
++#if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
++      [PCF50606_REG_D1REGC1]  = 0x15, /* VRF_3V: off */
++#elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3) || \
++      defined(CONFIG_ARCH_GTA01B_v4)
++      [PCF50606_REG_D1REGC1]  = 0x16, /* BT_3V15: off */
++#endif
++
++#if defined(CONFIG_ARCH_GTA01_v3)
++      [PCF50606_REG_D2REGC1]  = 0xf8, /* SD_3V3: on */
++#elif defined(CONFIG_ARCH_GTA01_v4) || defined(CONFIG_ARCH_GTA01B_v2) || \
++      defined(CONFIG_ARCH_GTA01B_v3) || defined(CONFIG_ARCH_GTA01B_v4)
++      [PCF50606_REG_D2REGC1]  = 0x10, /* GL_2V5: off */
++#endif
++
++#if defined(CONFIG_ARCH_GTA01_v3)
++      [PCF50606_REG_D3REGC1]  = 0x18, /* CODEC_3V3: off */
++#elif defined(CONFIG_ARCH_GTA01_v4)
++      [PCF50606_REG_D3REGC1]  = 0x13, /* VTXCO_2V8: off */
++#elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
++      [PCF50606_REG_D3REGC1]  = 0x00, /* USER1: off */
++#elif defined(CONFIG_ARCH_GTA01B_v4)
++      [PCF50606_REG_D3REGC1]  = 0xec, /* STBY_1V8: 2.1V */
++#endif
++
++      [PCF50606_REG_LPREGC1]  = 0xf8, /* LCM_3V3: on */
++      [PCF50606_REG_LPREGC2]  = 0x00,
++
++      [PCF50606_REG_MBCC1]    = 0x01, /* CHGAPE */
++      [PCF50606_REG_MBCC2]    = 0x00, /* unlimited charging */
++      [PCF50606_REG_MBCC3]    = 0x1a, /* 0.2*Ifast, 4.20V */
++      [PCF50606_REG_BBCC]     = 0x1f, /* 400uA */
++      [PCF50606_REG_ADCC1]    = 0x00,
++      [PCF50606_REG_ADCC2]    = 0x00,
++      /* gap */
++#if defined(CONFIG_ARCH_GTA01B_v4)
++      [PCF50606_REG_ACDC1]    = 0x86, /* ACD thresh 1.6V, enabled */
++#else
++      [PCF50606_REG_ACDC1]    = 0x00,
++#endif
++      [PCF50606_REG_BVMC]     = PCF50606_BVMC_THRSHLD_3V3,
++      [PCF50606_REG_PWMC1]    = 0x00,
++      [PCF50606_REG_LEDC1]    = 0x00,
++      [PCF50606_REG_LEDC2]    = 0x00,
++      [PCF50606_REG_GPOC1]    = 0x00,
++      [PCF50606_REG_GPOC2]    = 0x00,
++      [PCF50606_REG_GPOC3]    = 0x00,
++      [PCF50606_REG_GPOC4]    = 0x00,
++      [PCF50606_REG_GPOC5]    = 0x00,
++};
++
++
+Index: u-boot/board/neo1973/gta01/split_by_variant.sh
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/gta01/split_by_variant.sh
+@@ -0,0 +1,57 @@
++#!/bin/sh
++# ---------------------------------------------------------
++#  Set the core module defines according to Core Module
++# ---------------------------------------------------------
++# ---------------------------------------------------------
++# Set up the GTA01 type define
++# ---------------------------------------------------------
++
++CFGINC=${obj}include/config.h
++CFGTMP=${obj}board/neo1973/gta01/config.tmp
++
++mkdir -p ${obj}include
++if [ "$1" == "" ]
++then
++      echo "$0:: No parameters - using GTA01Bv3 config"
++      echo "#define CONFIG_ARCH_GTA01B_v3" > $CFGINC
++      echo "GTA01_BIG_RAM=y" > $CFGTMP
++else
++      case "$1" in
++      gta01v4_config)
++      echo "#define CONFIG_ARCH_GTA01_v4" > $CFGINC
++      echo "GTA01_BIG_RAM=n" > $CFGTMP
++      ;;
++
++      gta01v3_config)
++      echo "#define CONFIG_ARCH_GTA01_v3" > $CFGINC
++      echo "GTA01_BIG_RAM=n" > $CFGTMP
++      ;;
++
++      gta01bv2_config)
++      echo "#define CONFIG_ARCH_GTA01B_v2" > $CFGINC
++      echo "GTA01_BIG_RAM=y" > $CFGTMP
++      ;;
++
++      gta01bv3_config)
++      echo "#define CONFIG_ARCH_GTA01B_v3" > $CFGINC
++      echo "GTA01_BIG_RAM=y" > $CFGTMP
++      ;;
++
++      gta01bv4_config)
++      echo "#define CONFIG_ARCH_GTA01B_v4" > $CFGINC
++      echo "GTA01_BIG_RAM=y" > $CFGTMP
++      ;;
++
++      *)
++      echo "$0:: Unrecognised config - using GTA01Bv4 config"
++      echo "#define CONFIG_ARCH_GTA01B_v4" > $CFGINC
++      echo "GTA01_BIG_RAM=y" > $CFGTMP
++      ;;
++
++      esac
++
++fi
++# ---------------------------------------------------------
++# Complete the configuration
++# ---------------------------------------------------------
++$MKCONFIG -a neo1973_gta01 arm arm920t gta01 neo1973 s3c24x0
+Index: u-boot/board/neo1973/gta01/u-boot.lds
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/gta01/u-boot.lds
+@@ -0,0 +1,58 @@
++/*
++ * (C) Copyright 2002
++ * Gary Jennejohn, DENX Software Engineering, <gj@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_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
++OUTPUT_ARCH(arm)
++ENTRY(_start)
++SECTIONS
++{
++      . = 0x00000000;
++
++      . = ALIGN(4);
++      .text      :
++      {
++        cpu/arm920t/start.o   (.text)
++        cpu/arm920t/s3c24x0/nand_read.o (.text)
++        *(.text)
++      }
++
++      . = ALIGN(4);
++      .rodata : { *(.rodata) }
++
++      . = ALIGN(4);
++      .data : { *(.data) }
++
++      . = ALIGN(4);
++      .got : { *(.got) }
++
++      . = .;
++      __u_boot_cmd_start = .;
++      .u_boot_cmd : { *(.u_boot_cmd) }
++      __u_boot_cmd_end = .;
++
++      . = ALIGN(4);
++      __bss_start = .;
++      .bss : { *(.bss) }
++      _end = .;
++}
+Index: u-boot/include/configs/neo1973_gta01.h
+===================================================================
+--- /dev/null
++++ u-boot/include/configs/neo1973_gta01.h
+@@ -0,0 +1,265 @@
++/*
++ * (C) Copyright 2006 OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * Configuation settings for the FIC Neo1973 GTA01 Linux GSM phone
++ *
++ * 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
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#if defined(BUILD_FOR_RAM)
++/* If we want to start u-boot from inside RAM */
++#define CONFIG_SKIP_RELOCATE_UBOOT    1
++#define CONFIG_SKIP_LOWLEVEL_INIT     1
++#else
++/* we want to start u-boot directly from within NAND flash */
++#define CONFIG_S3C2410_NAND_BOOT      1
++#define CONFIG_S3C2410_NAND_SKIP_BAD  1
++#endif
++
++#define CFG_UBOOT_SIZE                0x40000 /* size of u-boot, for NAND loading */
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++#define CONFIG_ARM920T                1       /* This is an ARM920T Core      */
++#define       CONFIG_S3C2410          1       /* in a SAMSUNG S3C2410 SoC     */
++#define CONFIG_SMDK2410               1       /* on a SAMSUNG SMDK2410 Board  */
++
++/* input clock of PLL */
++#define CONFIG_SYS_CLK_FREQ   12000000/* the GTA01 has 12MHz input clock */
++
++
++#define USE_920T_MMU          1
++#define CONFIG_USE_IRQ                1
++
++/*
++ * Size of malloc() pool
++ */
++#define CFG_MALLOC_LEN                (CFG_ENV_SIZE + 128*1024)
++#define CFG_GBL_DATA_SIZE     128     /* size in bytes reserved for initial data */
++
++/*
++ * Hardware drivers
++ */
++
++/*
++ * select serial console configuration
++ */
++#define CONFIG_SERIAL1          1     /* we use SERIAL 1 on GTA01 */
++
++/************************************************************
++ * RTC
++ ************************************************************/
++#define       CONFIG_RTC_S3C24X0      1
++
++/* allow to overwrite serial and ethaddr */
++#define CONFIG_ENV_OVERWRITE
++
++#define CONFIG_BAUDRATE               115200
++
++/***********************************************************
++ * Command definition
++ ***********************************************************/
++#define CONFIG_COMMANDS (\
++                      CFG_CMD_BDI      | \
++                      CFG_CMD_LOADS    | \
++                      CFG_CMD_LAODB    | \
++                      CFG_CMD_IMI      | \
++                      CFG_CMD_CACHE    | \
++                      CFG_CMD_MEMORY   | \
++                      CFG_CMD_ENV      | \
++                      /* CFG_CMD_IRQ   | */  \
++                      CFG_CMD_BOOTD    | \
++                      CFG_CMD_CONSOLE  | \
++                      CFG_CMD_ASKENV   | \
++                      CFG_CMD_RUN      | \
++                      CFG_CMD_ECHO     | \
++                      CFG_CMD_I2C      | \
++                      CFG_CMD_REGINFO  | \
++                      CFG_CMD_IMMAP    | \
++                      CFG_CMD_DATE     | \
++                      CFG_CMD_AUTOSCRIPT | \
++                      CFG_CMD_BSP      | \
++                      CFG_CMD_ELF      | \
++                      CFG_CMD_MISC     | \
++                      /* CFG_CMD_USB   | */ \
++                      /* CFG_CMD_JFFS2         | */ \
++                      CFG_CMD_DIAG     | \
++                      /* CFG_CMD_HWFLOW        | */ \
++                      CFG_CMD_SAVES    | \
++                      CFG_CMD_NAND     | \
++                      CFG_CMD_PORTIO   | \
++                      CFG_CMD_MMC      | \
++                      CFG_CMD_FAT      | \
++                      CFG_CMD_EXT2     | \
++                      0)
++/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
++#include <cmd_confdefs.h>
++
++#define CONFIG_BOOTDELAY      3
++#define CONFIG_BOOTARGS       "rootfstype=jffs2 root=/dev/mtdblock4 console=ttySAC0,115200 console=tty0 loglevel=8"
++#define CONFIG_BOOTCOMMAND    "nand read.e 0x32000000 0x34000 0x200000; bootm 0x32000000"
++
++#define CONFIG_DOS_PARTITION  1
++
++#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
++#define CONFIG_KGDB_BAUDRATE  115200          /* speed to run kgdb serial port */
++/* what's this ? it's not used anywhere */
++#define CONFIG_KGDB_SER_INDEX 1               /* which serial port to use */
++#endif
++
++/*
++ * Miscellaneous configurable options
++ */
++#define       CFG_LONGHELP                            /* undef to save memory         */
++#if defined(CONFIG_ARCH_GTA01_v3)
++#define       CFG_PROMPT              "GTA01v3 # "    /* Monitor Command Prompt       */
++#elif defined(CONFIG_ARCH_GTA01_v4)
++#define       CFG_PROMPT              "GTA01v4 # "    /* Monitor Command Prompt       */
++#elif defined(CONFIG_ARCH_GTA01B_v2)
++#define       CFG_PROMPT              "GTA01Bv2 # "   /* Monitor Command Prompt       */
++#elif defined(CONFIG_ARCH_GTA01B_v3)
++#define       CFG_PROMPT              "GTA01Bv3 # "   /* Monitor Command Prompt       */
++#elif defined(CONFIG_ARCH_GTA01B_v4)
++#define       CFG_PROMPT              "GTA01Bv4 # "   /* Monitor Command Prompt       */
++#endif
++#define       CFG_CBSIZE              256             /* Console I/O Buffer Size      */
++#define       CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
++#define       CFG_MAXARGS             16              /* max number of command args   */
++#define CFG_BARGSIZE          CFG_CBSIZE      /* Boot Argument Buffer Size    */
++
++#define CFG_MEMTEST_START     0x30000000      /* memtest works on     */
++#define CFG_MEMTEST_END               0x33F00000      /* 63 MB in DRAM        */
++
++#undef  CFG_CLKS_IN_HZ                /* everything, incl board info, in Hz */
++
++#define       CFG_LOAD_ADDR           0x33000000      /* default load address */
++
++/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
++/* it to wrap 100 times (total 1562500) to get 1 sec. */
++#define       CFG_HZ                  1562500
++
++/* valid baudrates */
++#define CFG_BAUDRATE_TABLE    { 9600, 19200, 38400, 57600, 115200 }
++
++/*-----------------------------------------------------------------------
++ * Stack sizes
++ *
++ * The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE      (128*1024)      /* regular stack */
++#ifdef CONFIG_USE_IRQ
++#define CONFIG_STACKSIZE_IRQ  (4*1024)        /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ  (4*1024)        /* FIQ stack */
++#endif
++
++#if 0
++#define CONFIG_USB_OHCI               1
++#endif
++
++/*-----------------------------------------------------------------------
++ * Physical Memory Map
++ */
++#define CONFIG_NR_DRAM_BANKS  1          /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1          0x30000000 /* SDRAM Bank #1 */
++#if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
++#define PHYS_SDRAM_1_SIZE     0x04000000 /* 64 MB */
++#elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3) || \
++      defined(CONFIG_ARCH_GTA01B_v4)
++#define PHYS_SDRAM_1_SIZE     0x08000000 /* 128 MB */
++#else
++#error Please define GTA01 variant
++#endif
++#define PHYS_SDRAM_RES_SIZE   0x00200000 /* 2 MB for frame buffer */
++
++/*-----------------------------------------------------------------------
++ * FLASH and environment organization
++ */
++
++/* No NOR flash in this device */
++#define CFG_NO_FLASH          1
++
++#define       CFG_ENV_IS_IN_NAND      1
++#define CFG_ENV_SIZE          0x4000          /* 16k Total Size of Environment Sector */
++#define CFG_ENV_OFFSET_OOB    1               /* Location of ENV stored in block 0 OOB */
++
++#define NAND_MAX_CHIPS                1
++#define CFG_NAND_BASE         0x4e000000
++#define CFG_MAX_NAND_DEVICE   1
++
++#define CONFIG_MMC            1
++#define CFG_MMC_BASE          0xff000000
++
++/* EXT2 driver */
++#define CONFIG_EXT2           1
++
++#define CONFIG_FAT            1
++#define CONFIG_SUPPORT_VFAT
++
++#if 0
++/* JFFS2 driver */
++#define CONFIG_JFFS2_CMDLINE  1
++#define CONFIG_JFFS2_NAND     1
++#define CONFIG_JFFS2_NAND_DEV 0
++#define CONFIG_JFFS2_NAND_OFF 0x634000
++#define CONFIG_JFFS2_NAND_SIZE        0x39cc000
++#endif
++
++/* ATAG configuration */
++#define CONFIG_INITRD_TAG             1
++#define CONFIG_SETUP_MEMORY_TAGS      1
++#define CONFIG_CMDLINE_TAG            1
++#define CONFIG_REVISION_TAG           1
++#if 0
++#define CONFIG_SERIAL_TAG             1
++#endif
++
++#define CONFIG_DRIVER_S3C24X0_I2C     1
++#define CONFIG_HARD_I2C                       1
++#define CFG_I2C_SPEED                 400000  /* 400kHz according to PCF50606 data sheet */
++#define CFG_I2C_SLAVE                 0x7f
++
++/* we have a board_late_init() function */
++#define BOARD_LATE_INIT                       1
++
++#if 1
++#define CONFIG_VIDEO
++#define CONFIG_VIDEO_S3C2410
++#define CONFIG_CFB_CONSOLE
++#define CONFIG_VIDEO_LOGO
++#define CONFIG_VGA_AS_SINGLE_DEVICE
++
++#define VIDEO_KBD_INIT_FCT    0
++#define VIDEO_TSTC_FCT                serial_tstc
++#define VIDEO_GETC_FCT                serial_getc
++
++#define LCD_VIDEO_ADDR                0x33d00000
++#endif
++
++#define CONFIG_S3C2410_NAND_BBT                1
++#define CONFIG_S3C2410_NAND_HWECC              1
++
++#define CONFIG_DRIVER_PCF50606                1
++
++#endif        /* __CONFIG_H */
+Index: u-boot/board/neo1973/common/neo1973.h
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/common/neo1973.h
+@@ -0,0 +1,32 @@
++#ifndef _NEO1973_H
++#define _NEO1973_H
++
++enum wakeup_reason {
++      NEO1973_WAKEUP_NONE,
++      NEO1973_WAKEUP_RESET,
++      NEO1973_WAKEUP_POWER_KEY,
++      NEO1973_WAKEUP_CHARGER,
++      NEO1973_WAKEUP_ALARM,
++};
++
++enum neo1973_charger_cmd {
++      NEO1973_CHGCMD_NONE,
++      NEO1973_CHGCMD_AUTOFAST,
++      NEO1973_CHGCMD_NO_AUTOFAST,
++      NEO1973_CHGCMD_OFF,
++      NEO1973_CHGCMD_FAST,
++      NEO1973_CHGCMD_FASTER,
++};
++
++extern unsigned int neo1973_wakeup_cause;
++
++void neo1973_poweroff(void);
++void neo1973_backlight(int on);
++void neo1973_vibrator(int on);
++
++int neo1973_911_key_pressed(void);
++
++const char *neo1973_get_charge_status(void);
++int neo1973_set_charge_mode(enum neo1973_charger_cmd cmd);
++
++#endif
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-20061030-qt2410.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-20061030-qt2410.patch
new file mode 100644 (file)
index 0000000..3435989
--- /dev/null
@@ -0,0 +1,1233 @@
+This patch adds 'board' support for the Armzone QT2410
+development board to u-boot.
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+
+Index: u-boot/Makefile
+===================================================================
+--- u-boot.orig/Makefile
++++ u-boot/Makefile
+@@ -2009,6 +2009,9 @@
+ sbc2410x_config: unconfig
+       @$(MKCONFIG) $(@:_config=) arm arm920t sbc2410x NULL s3c24x0
++qt2410_config :       unconfig
++      @./mkconfig $(@:_config=) arm arm920t qt2410 NULL s3c24x0
++
+ scb9328_config        :       unconfig
+       @$(MKCONFIG) $(@:_config=) arm arm920t scb9328 NULL imx
+Index: u-boot/board/qt2410/Makefile
+===================================================================
+--- /dev/null
++++ u-boot/board/qt2410/Makefile
+@@ -0,0 +1,47 @@
++#
++# (C) Copyright 2000, 2001, 2002
++# Wolfgang Denk, DENX Software Engineering, wd@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
++#
++
++include $(TOPDIR)/config.mk
++
++LIB   = lib$(BOARD).a
++
++OBJS  := qt2410.o flash.o
++SOBJS := lowlevel_init.o
++
++$(LIB):       $(OBJS) $(SOBJS)
++      $(AR) crv $@ $(OBJS) $(SOBJS)
++
++clean:
++      rm -f $(SOBJS) $(OBJS)
++
++distclean:    clean
++      rm -f $(LIB) core *.bak .depend
++
++#########################################################################
++
++.depend:      Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
++              $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
++
++-include .depend
++
++#########################################################################
+Index: u-boot/board/qt2410/config.mk
+===================================================================
+--- /dev/null
++++ u-boot/board/qt2410/config.mk
+@@ -0,0 +1,29 @@
++#
++# (C) Copyright 2002
++# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
++# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++#
++# SAMSUNG SMDK2410 board with S3C2410X (ARM920T) cpu
++#
++# see http://www.samsung.com/ for more information on SAMSUNG
++#
++
++CONFIG_USB_DFU_VENDOR=0x1457
++CONFIG_USB_DFU_PRODUCT=0x511d
++CONFIG_USB_DFU_REVISION=0x0100
++
++#
++# SMDK2410 has 1 bank of 64 MB DRAM
++#
++# 3000'0000 to 3400'0000
++#
++# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
++# optionally with a ramdisk at 3080'0000
++#
++# we load ourself to 33F8'0000
++#
++# download area is 3300'0000
++#
++
++
++TEXT_BASE = 0x33F80000
+Index: u-boot/board/qt2410/flash.c
+===================================================================
+--- /dev/null
++++ u-boot/board/qt2410/flash.c
+@@ -0,0 +1,435 @@
++/*
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Alex Zuepke <azu@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>
++
++ulong myflush (void);
++
++
++#define FLASH_BANK_SIZE       PHYS_FLASH_SIZE
++#define MAIN_SECT_SIZE  0x10000       /* 64 KB */
++
++flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
++
++
++#define CMD_READ_ARRAY                0x000000F0
++#define CMD_UNLOCK1           0x000000AA
++#define CMD_UNLOCK2           0x00000055
++#define CMD_ERASE_SETUP               0x00000080
++#define CMD_ERASE_CONFIRM     0x00000030
++#define CMD_PROGRAM           0x000000A0
++#define CMD_UNLOCK_BYPASS     0x00000020
++
++#define MEM_FLASH_ADDR1               (*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555 << 1)))
++#define MEM_FLASH_ADDR2               (*(volatile u16 *)(CFG_FLASH_BASE + (0x000002AA << 1)))
++
++#define BIT_ERASE_DONE                0x00000080
++#define BIT_RDY_MASK          0x00000080
++#define BIT_PROGRAM_ERROR     0x00000020
++#define BIT_TIMEOUT           0x80000000      /* our flag */
++
++#define READY 1
++#define ERR   2
++#define TMO   4
++
++/*-----------------------------------------------------------------------
++ */
++
++ulong flash_init (void)
++{
++      int i, j;
++      ulong size = 0;
++
++      for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
++              ulong flashbase = 0;
++
++              flash_info[i].flash_id =
++#if defined(CONFIG_AMD_LV400)
++                      (AMD_MANUFACT & FLASH_VENDMASK) |
++                      (AMD_ID_LV400B & FLASH_TYPEMASK);
++#elif defined(CONFIG_AMD_LV800)
++                      (AMD_MANUFACT & FLASH_VENDMASK) |
++                      (AMD_ID_LV800B & FLASH_TYPEMASK);
++#else
++#error "Unknown flash configured"
++#endif
++                      flash_info[i].size = FLASH_BANK_SIZE;
++              flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
++              memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
++              if (i == 0)
++                      flashbase = PHYS_FLASH_1;
++              else
++                      panic ("configured too many flash banks!\n");
++              for (j = 0; j < flash_info[i].sector_count; j++) {
++                      if (j <= 3) {
++                              /* 1st one is 16 KB */
++                              if (j == 0) {
++                                      flash_info[i].start[j] =
++                                              flashbase + 0;
++                              }
++
++                              /* 2nd and 3rd are both 8 KB */
++                              if ((j == 1) || (j == 2)) {
++                                      flash_info[i].start[j] =
++                                              flashbase + 0x4000 + (j -
++                                                                    1) *
++                                              0x2000;
++                              }
++
++                              /* 4th 32 KB */
++                              if (j == 3) {
++                                      flash_info[i].start[j] =
++                                              flashbase + 0x8000;
++                              }
++                      } else {
++                              flash_info[i].start[j] =
++                                      flashbase + (j - 3) * MAIN_SECT_SIZE;
++                      }
++              }
++              size += flash_info[i].size;
++      }
++
++      flash_protect (FLAG_PROTECT_SET,
++                     CFG_FLASH_BASE,
++                     CFG_FLASH_BASE + monitor_flash_len - 1,
++                     &flash_info[0]);
++
++#if 0
++      flash_protect (FLAG_PROTECT_SET,
++                     CFG_ENV_ADDR,
++                     CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
++#endif
++
++      return size;
++}
++
++/*-----------------------------------------------------------------------
++ */
++void flash_print_info (flash_info_t * info)
++{
++      int i;
++
++      switch (info->flash_id & FLASH_VENDMASK) {
++      case (AMD_MANUFACT & FLASH_VENDMASK):
++              printf ("AMD: ");
++              break;
++      default:
++              printf ("Unknown Vendor ");
++              break;
++      }
++
++      switch (info->flash_id & FLASH_TYPEMASK) {
++      case (AMD_ID_LV400B & FLASH_TYPEMASK):
++              printf ("1x Amd29LV400BB (4Mbit)\n");
++              break;
++      case (AMD_ID_LV800B & FLASH_TYPEMASK):
++              printf ("1x Amd29LV800BB (8Mbit)\n");
++              break;
++      default:
++              printf ("Unknown Chip Type\n");
++              goto Done;
++              break;
++      }
++
++      printf ("  Size: %ld MB in %d Sectors\n",
++              info->size >> 20, info->sector_count);
++
++      printf ("  Sector Start Addresses:");
++      for (i = 0; i < info->sector_count; i++) {
++              if ((i % 5) == 0) {
++                      printf ("\n   ");
++              }
++              printf (" %08lX%s", info->start[i],
++                      info->protect[i] ? " (RO)" : "     ");
++      }
++      printf ("\n");
++
++      Done:;
++}
++
++/*-----------------------------------------------------------------------
++ */
++
++int flash_erase (flash_info_t * info, int s_first, int s_last)
++{
++      ushort result;
++      int iflag, cflag, prot, sect;
++      int rc = ERR_OK;
++      int chip;
++
++      /* first look for protection bits */
++
++      if (info->flash_id == FLASH_UNKNOWN)
++              return ERR_UNKNOWN_FLASH_TYPE;
++
++      if ((s_first < 0) || (s_first > s_last)) {
++              return ERR_INVAL;
++      }
++
++      if ((info->flash_id & FLASH_VENDMASK) !=
++          (AMD_MANUFACT & FLASH_VENDMASK)) {
++              return ERR_UNKNOWN_FLASH_VENDOR;
++      }
++
++      prot = 0;
++      for (sect = s_first; sect <= s_last; ++sect) {
++              if (info->protect[sect]) {
++                      prot++;
++              }
++      }
++      if (prot)
++              return ERR_PROTECTED;
++
++      /*
++       * Disable interrupts which might cause a timeout
++       * here. Remember that our exception vectors are
++       * at address 0 in the flash, and we don't want a
++       * (ticker) exception to happen while the flash
++       * chip is in programming mode.
++       */
++      cflag = icache_status ();
++      icache_disable ();
++      iflag = disable_interrupts ();
++
++      /* Start erase on unprotected sectors */
++      for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
++              printf ("Erasing sector %2d ... ", sect);
++
++              /* arm simple, non interrupt dependent timer */
++              reset_timer_masked ();
++
++              if (info->protect[sect] == 0) { /* not protected */
++                      vu_short *addr = (vu_short *) (info->start[sect]);
++
++                      MEM_FLASH_ADDR1 = CMD_UNLOCK1;
++                      MEM_FLASH_ADDR2 = CMD_UNLOCK2;
++                      MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
++
++                      MEM_FLASH_ADDR1 = CMD_UNLOCK1;
++                      MEM_FLASH_ADDR2 = CMD_UNLOCK2;
++                      *addr = CMD_ERASE_CONFIRM;
++
++                      /* wait until flash is ready */
++                      chip = 0;
++
++                      do {
++                              result = *addr;
++
++                              /* check timeout */
++                              if (get_timer_masked () >
++                                  CFG_FLASH_ERASE_TOUT) {
++                                      MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
++                                      chip = TMO;
++                                      break;
++                              }
++
++                              if (!chip
++                                  && (result & 0xFFFF) & BIT_ERASE_DONE)
++                                      chip = READY;
++
++                              if (!chip
++                                  && (result & 0xFFFF) & BIT_PROGRAM_ERROR)
++                                      chip = ERR;
++
++                      } while (!chip);
++
++                      MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
++
++                      if (chip == ERR) {
++                              rc = ERR_PROG_ERROR;
++                              goto outahere;
++                      }
++                      if (chip == TMO) {
++                              rc = ERR_TIMOUT;
++                              goto outahere;
++                      }
++
++                      printf ("ok.\n");
++              } else {        /* it was protected */
++
++                      printf ("protected!\n");
++              }
++      }
++
++      if (ctrlc ())
++              printf ("User Interrupt!\n");
++
++      outahere:
++      /* allow flash to settle - wait 10 ms */
++      udelay_masked (10000);
++
++      if (iflag)
++              enable_interrupts ();
++
++      if (cflag)
++              icache_enable ();
++
++      return rc;
++}
++
++/*-----------------------------------------------------------------------
++ * Copy memory to flash
++ */
++
++volatile static int write_hword (flash_info_t * info, ulong dest, ushort data)
++{
++      vu_short *addr = (vu_short *) dest;
++      ushort result;
++      int rc = ERR_OK;
++      int cflag, iflag;
++      int chip;
++
++      /*
++       * Check if Flash is (sufficiently) erased
++       */
++      result = *addr;
++      if ((result & data) != data)
++              return ERR_NOT_ERASED;
++
++
++      /*
++       * Disable interrupts which might cause a timeout
++       * here. Remember that our exception vectors are
++       * at address 0 in the flash, and we don't want a
++       * (ticker) exception to happen while the flash
++       * chip is in programming mode.
++       */
++      cflag = icache_status ();
++      icache_disable ();
++      iflag = disable_interrupts ();
++
++      MEM_FLASH_ADDR1 = CMD_UNLOCK1;
++      MEM_FLASH_ADDR2 = CMD_UNLOCK2;
++      MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
++      *addr = CMD_PROGRAM;
++      *addr = data;
++
++      /* arm simple, non interrupt dependent timer */
++      reset_timer_masked ();
++
++      /* wait until flash is ready */
++      chip = 0;
++      do {
++              result = *addr;
++
++              /* check timeout */
++              if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
++                      chip = ERR | TMO;
++                      break;
++              }
++              if (!chip && ((result & 0x80) == (data & 0x80)))
++                      chip = READY;
++
++              if (!chip && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) {
++                      result = *addr;
++
++                      if ((result & 0x80) == (data & 0x80))
++                              chip = READY;
++                      else
++                              chip = ERR;
++              }
++
++      } while (!chip);
++
++      *addr = CMD_READ_ARRAY;
++
++      if (chip == ERR || *addr != data)
++              rc = ERR_PROG_ERROR;
++
++      if (iflag)
++              enable_interrupts ();
++
++      if (cflag)
++              icache_enable ();
++
++      return rc;
++}
++
++/*-----------------------------------------------------------------------
++ * Copy memory to flash.
++ */
++
++int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
++{
++      ulong cp, wp;
++      int l;
++      int i, rc;
++      ushort data;
++
++      wp = (addr & ~1);       /* get lower word aligned address */
++
++      /*
++       * handle unaligned start bytes
++       */
++      if ((l = addr - wp) != 0) {
++              data = 0;
++              for (i = 0, cp = wp; i < l; ++i, ++cp) {
++                      data = (data >> 8) | (*(uchar *) cp << 8);
++              }
++              for (; i < 2 && cnt > 0; ++i) {
++                      data = (data >> 8) | (*src++ << 8);
++                      --cnt;
++                      ++cp;
++              }
++              for (; cnt == 0 && i < 2; ++i, ++cp) {
++                      data = (data >> 8) | (*(uchar *) cp << 8);
++              }
++
++              if ((rc = write_hword (info, wp, data)) != 0) {
++                      return (rc);
++              }
++              wp += 2;
++      }
++
++      /*
++       * handle word aligned part
++       */
++      while (cnt >= 2) {
++              data = *((vu_short *) src);
++              if ((rc = write_hword (info, wp, data)) != 0) {
++                      return (rc);
++              }
++              src += 2;
++              wp += 2;
++              cnt -= 2;
++      }
++
++      if (cnt == 0) {
++              return ERR_OK;
++      }
++
++      /*
++       * handle unaligned tail bytes
++       */
++      data = 0;
++      for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
++              data = (data >> 8) | (*src++ << 8);
++              --cnt;
++      }
++      for (; i < 2; ++i, ++cp) {
++              data = (data >> 8) | (*(uchar *) cp << 8);
++      }
++
++      return write_hword (info, wp, data);
++}
+Index: u-boot/board/qt2410/lowlevel_init.S
+===================================================================
+--- /dev/null
++++ u-boot/board/qt2410/lowlevel_init.S
+@@ -0,0 +1,171 @@
++/*
++ * Memory Setup stuff - taken from blob memsetup.S
++ *
++ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
++ *                     Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
++ *
++ * Modified for the Samsung SMDK2410 by
++ * (C) Copyright 2002
++ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++ *
++ * 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 <version.h>
++
++
++/* some parameters for the board */
++
++/*
++ *
++ * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
++ *
++ * Copyright (C) 2002 Samsung Electronics SW.LEE  <hitchcar@sec.samsung.com>
++ *
++ */
++
++#define BWSCON        0x48000000
++
++/* BWSCON */
++#define DW8                   (0x0)
++#define DW16                  (0x1)
++#define DW32                  (0x2)
++#define WAIT                  (0x1<<2)
++#define UBLB                  (0x1<<3)
++
++#define B1_BWSCON             (DW32)
++#define B2_BWSCON             (DW16)
++#define B3_BWSCON             (DW16 + WAIT + UBLB)
++#define B4_BWSCON             (DW16)
++#define B5_BWSCON             (DW16)
++#define B6_BWSCON             (DW32)
++#define B7_BWSCON             (DW32)
++
++/* BANK0CON */
++#define B0_Tacs                       0x0     /*  0clk */
++#define B0_Tcos                       0x0     /*  0clk */
++#define B0_Tacc                       0x7     /* 14clk */
++#define B0_Tcoh                       0x0     /*  0clk */
++#define B0_Tah                        0x0     /*  0clk */
++#define B0_Tacp                       0x0
++#define B0_PMC                        0x0     /* normal */
++
++/* BANK1CON */
++#define B1_Tacs                       0x0     /*  0clk */
++#define B1_Tcos                       0x0     /*  0clk */
++#define B1_Tacc                       0x7     /* 14clk */
++#define B1_Tcoh                       0x0     /*  0clk */
++#define B1_Tah                        0x0     /*  0clk */
++#define B1_Tacp                       0x0
++#define B1_PMC                        0x0
++
++#define B2_Tacs                       0x0
++#define B2_Tcos                       0x0
++#define B2_Tacc                       0x7
++#define B2_Tcoh                       0x0
++#define B2_Tah                        0x0
++#define B2_Tacp                       0x0
++#define B2_PMC                        0x0
++
++#define B3_Tacs                       0x0     /*  0clk */
++#define B3_Tcos                       0x3     /*  4clk */
++#define B3_Tacc                       0x7     /* 14clk */
++#define B3_Tcoh                       0x1     /*  1clk */
++#define B3_Tah                        0x0     /*  0clk */
++#define B3_Tacp                       0x3     /*  6clk */
++#define B3_PMC                        0x0     /* normal */
++
++#define B4_Tacs                       0x0     /*  0clk */
++#define B4_Tcos                       0x0     /*  0clk */
++#define B4_Tacc                       0x7     /* 14clk */
++#define B4_Tcoh                       0x0     /*  0clk */
++#define B4_Tah                        0x0     /*  0clk */
++#define B4_Tacp                       0x0
++#define B4_PMC                        0x0     /* normal */
++
++#define B5_Tacs                       0x0     /*  0clk */
++#define B5_Tcos                       0x0     /*  0clk */
++#define B5_Tacc                       0x7     /* 14clk */
++#define B5_Tcoh                       0x0     /*  0clk */
++#define B5_Tah                        0x0     /*  0clk */
++#define B5_Tacp                       0x0
++#define B5_PMC                        0x0     /* normal */
++
++#define B6_MT                 0x3     /* SDRAM */
++#define B6_Trcd                       0x1
++#define B6_SCAN                       0x1     /* 9bit */
++
++#define B7_MT                 0x3     /* SDRAM */
++#define B7_Trcd                       0x1     /* 3clk */
++#define B7_SCAN                       0x1     /* 9bit */
++
++/* REFRESH parameter */
++#define REFEN                 0x1     /* Refresh enable */
++#define TREFMD                        0x0     /* CBR(CAS before RAS)/Auto refresh */
++#define Trp                   0x1     /* 3clk */
++#define Trc                   0x3     /* 7clk */
++#define Tchr                  0x2     /* 3clk */
++//#define REFCNT                      1113    /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
++#define REFCNT                        997     /* period=17.5us, HCLK=60Mhz, (2048+1-15.6*60) */
++/**************************************/
++
++_TEXT_BASE:
++      .word   TEXT_BASE
++
++.globl lowlevel_init
++lowlevel_init:
++      /* memory control configuration */
++      /* make r0 relative the current location so that it */
++      /* reads SMRDATA out of FLASH rather than memory ! */
++      adr     r0, SMRDATA
++      ldr     r1, =BWSCON     /* Bus Width Status Controller */
++      add     r2, r0, #13*4
++0:
++      ldr     r3, [r0], #4
++      str     r3, [r1], #4
++      cmp     r2, r0
++      bne     0b
++
++      /* setup asynchronous bus mode */
++      mrc     p15, 0, r1 ,c1 ,c0, 0
++      orr     r1, r1, #0xc0000000
++      mcr     p15, 0, r1, c1, c0, 0
++
++      /* everything is fine now */
++      mov     pc, lr
++
++      .ltorg
++/* the literal pools origin */
++
++SMRDATA:
++    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
++    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
++    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
++    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
++    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
++    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
++    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
++    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
++    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
++    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
++    .word 0xb2
++    .word 0x30
++    .word 0x30
+Index: u-boot/board/qt2410/qt2410.c
+===================================================================
+--- /dev/null
++++ u-boot/board/qt2410/qt2410.c
+@@ -0,0 +1,152 @@
++/*
++ * (C) 2006 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * based on existing S3C2410 startup code in u-boot:
++ *
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Marius Groeger <mgroeger@sysgo.de>
++ *
++ * (C) Copyright 2002
++ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++ *
++ * 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 <video_fb.h>
++#include <usbdcore.h>
++#include <s3c2410.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#if 1
++//#define M_MDIV      0xA1            /* Fout = 202.8MHz */
++//#define M_PDIV      0x3
++//#define M_SDIV      0x1
++#define M_MDIV        0x90            /* Fout = 202.8MHz */
++#define M_PDIV        0x7
++#define M_SDIV        0x0
++#else
++#define M_MDIV        0x5c            /* Fout = 150.0MHz */
++#define M_PDIV        0x4
++#define M_SDIV        0x0
++#endif
++
++#if 1
++#define U_M_MDIV      0x78
++#define U_M_PDIV      0x2
++#define U_M_SDIV      0x3
++#else
++#define U_M_MDIV      0x48
++#define U_M_PDIV      0x3
++#define U_M_SDIV      0x2
++#endif
++
++static inline void delay (unsigned long loops)
++{
++      __asm__ volatile ("1:\n"
++        "subs %0, %1, #1\n"
++        "bne 1b":"=r" (loops):"0" (loops));
++}
++
++/*
++ * Miscellaneous platform dependent initialisations
++ */
++
++int board_init (void)
++{
++      S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++      /* to reduce PLL lock time, adjust the LOCKTIME register */
++      clk_power->LOCKTIME = 0xFFFFFF;
++
++      /* configure MPLL */
++      clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
++
++      /* some delay between MPLL and UPLL */
++      delay (4000);
++
++      /* configure UPLL */
++      clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
++
++      /* some delay between MPLL and UPLL */
++      delay (8000);
++
++      /* set up the I/O ports */
++      gpio->GPACON = 0x007FFFFF;
++      gpio->GPBCON = 0x00044555;
++      gpio->GPBUP = 0x000007FF;
++      gpio->GPCCON = 0xAAAAAAAA;
++      gpio->GPCUP = 0x0000FFFF;
++      gpio->GPDCON = 0xAAAAAAAA;
++      gpio->GPDUP = 0x0000FFFF;
++      gpio->GPECON = 0xAAAAAAAA;
++      gpio->GPEUP = 0x0000FFFF;
++      gpio->GPFCON = 0x000055AA;
++      gpio->GPFUP = 0x000000FF;
++      gpio->GPGCON = 0xFF95FFBA;
++      //gpio->GPGUP = 0x0000FFFF;
++      gpio->GPGUP = 0x0000AFEF;
++      gpio->GPHCON = 0x0028FAAA;
++      gpio->GPHUP = 0x000007FF;
++
++      /* arch number of SMDK2410-Board */
++      gd->bd->bi_arch_number = MACH_TYPE_QT2410;
++
++      /* adress of boot parameters */
++      gd->bd->bi_boot_params = 0x30000100;
++
++      icache_enable();
++      dcache_enable();
++
++      return 0;
++}
++
++#if defined(CONFIG_USB_DEVICE)
++void udc_ctrl(enum usbd_event event, int param)
++{
++}
++#endif
++
++void board_video_init(GraphicDevice *pGD)
++{
++      S3C24X0_LCD * const lcd = S3C24X0_GetBase_LCD();
++
++      /* FIXME: select LCM type by env variable */
++
++      /* Configuration for GTA01 LCM on QT2410 */
++      lcd->LCDCON1 = 0x00000178; /* CLKVAL=1, BPPMODE=16bpp, TFT, ENVID=0 */
++
++      lcd->LCDCON2 = 0x019fc3c1;
++      lcd->LCDCON3 = 0x0039df67;
++      lcd->LCDCON4 = 0x00000007;
++      lcd->LCDCON5 = 0x0001cf09;
++      lcd->LPCSEL  = 0x00000000;
++}
++
++int dram_init (void)
++{
++      gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
++      gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
++
++      return 0;
++}
+Index: u-boot/board/qt2410/u-boot.lds
+===================================================================
+--- /dev/null
++++ u-boot/board/qt2410/u-boot.lds
+@@ -0,0 +1,58 @@
++/*
++ * (C) Copyright 2002
++ * Gary Jennejohn, DENX Software Engineering, <gj@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_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
++OUTPUT_ARCH(arm)
++ENTRY(_start)
++SECTIONS
++{
++      . = 0x00000000;
++
++      . = ALIGN(4);
++      .text      :
++      {
++        cpu/arm920t/start.o   (.text)
++        cpu/arm920t/s3c24x0/nand_read.o (.text)
++        *(.text)
++      }
++
++      . = ALIGN(4);
++      .rodata : { *(.rodata) }
++
++      . = ALIGN(4);
++      .data : { *(.data) }
++
++      . = ALIGN(4);
++      .got : { *(.got) }
++
++      . = .;
++      __u_boot_cmd_start = .;
++      .u_boot_cmd : { *(.u_boot_cmd) }
++      __u_boot_cmd_end = .;
++
++      . = ALIGN(4);
++      __bss_start = .;
++      .bss : { *(.bss) }
++      _end = .;
++}
+Index: u-boot/include/configs/qt2410.h
+===================================================================
+--- /dev/null
++++ u-boot/include/configs/qt2410.h
+@@ -0,0 +1,287 @@
++/*
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Marius Groeger <mgroeger@sysgo.de>
++ * Gary Jennejohn <gj@denx.de>
++ * David Mueller <d.mueller@elsoft.ch>
++ *
++ * Configuation settings for the Armzone QT2410 board.
++ *
++ * 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
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#if 0
++/* If we want to start u-boot from usb bootloader in NOR flash */
++#define CONFIG_SKIP_RELOCATE_UBOOT    1
++#define       CONFIG_SKIP_LOWLEVEL_INIT       1
++#else
++/* If we want to start u-boot directly from within NAND flash */
++#define CONFIG_S3C2410_NAND_BOOT      1
++#define CONFIG_S3C2410_NAND_SKIP_BAD  1
++#endif
++
++#define CFG_UBOOT_SIZE            0x40000
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++#define CONFIG_ARM920T                1       /* This is an ARM920T Core      */
++#define       CONFIG_S3C2410          1       /* in a SAMSUNG S3C2410 SoC     */
++#define CONFIG_SMDK2410               1       /* on a SAMSUNG SMDK2410 Board  */
++
++/* input clock of PLL */
++#define CONFIG_SYS_CLK_FREQ   12000000/* the SMDK2410 has 12MHz input clock */
++
++
++#define USE_920T_MMU          1
++#define CONFIG_USE_IRQ                1
++
++/*
++ * Size of malloc() pool
++ */
++#define CFG_MALLOC_LEN                (CFG_ENV_SIZE + 400*1024)
++#define CFG_GBL_DATA_SIZE     128     /* size in bytes reserved for initial data */
++
++/*
++ * Hardware drivers
++ */
++#if 0
++#define CONFIG_DRIVER_CS8900  1       /* we have a CS8900 on-board */
++#define CS8900_BASE           0x19000300
++#define CS8900_BUS16          1 /* the Linux driver does accesses as shorts */
++#endif
++
++/*
++ * select serial console configuration
++ */
++#define CONFIG_SERIAL1          1     /* we use SERIAL 1 on SMDK2410 */
++#define CONFIG_HWFLOW         1
++
++/************************************************************
++ * RTC
++ ************************************************************/
++#define       CONFIG_RTC_S3C24X0      1
++
++/* allow to overwrite serial and ethaddr */
++#define CONFIG_ENV_OVERWRITE
++
++#define CONFIG_BAUDRATE               115200
++
++/***********************************************************
++ * Command definition
++ ***********************************************************/
++#define CONFIG_COMMANDS (\
++                      CFG_CMD_BDI      | \
++                      CFG_CMD_LOADS    | \
++                      CFG_CMD_LOADB    | \
++                      CFG_CMD_IMI      | \
++                      CFG_CMD_CACHE    | \
++                      CFG_CMD_MEMORY   | \
++                      CFG_CMD_ENV      | \
++                      /* CFG_CMD_IRQ   | */ \
++                      CFG_CMD_BOOTD    | \
++                      CFG_CMD_CONSOLE  | \
++                      CFG_CMD_BMP      | \
++                      CFG_CMD_ASKENV   | \
++                      CFG_CMD_RUN      | \
++                      CFG_CMD_ECHO     | \
++                      CFG_CMD_I2C      | \
++                      CFG_CMD_REGINFO  | \
++                      CFG_CMD_IMMAP    | \
++                      CFG_CMD_DATE     | \
++                      CFG_CMD_AUTOSCRIPT | \
++                      CFG_CMD_BSP      | \
++                      CFG_CMD_ELF      | \
++                      CFG_CMD_MISC     | \
++                      /* CFG_CMD_USB   | */ \
++                      CFG_CMD_JFFS2    | \
++                      CFG_CMD_DIAG     | \
++                      CFG_CMD_HWFLOW   | \
++                      CFG_CMD_SAVES    | \
++                      CFG_CMD_NAND     | \
++                      CFG_CMD_PORTIO   | \
++                      CFG_CMD_MMC      | \
++                      CFG_CMD_FAT      | \
++                      CFG_CMD_EXT2     | \
++                      0)
++
++#if 0
++                      CFG_CMD_DHCP     | \
++                      CFG_CMD_PING     | \
++                      CFG_CMD_NET      | \
++
++#endif
++
++/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
++#include <cmd_confdefs.h>
++
++#define CONFIG_BOOTDELAY      3
++#define CONFIG_BOOTARGS       "rootfstype=jffs2 root=/dev/mtdblock4 console=ttySAC0,115200 console=tty0 loglevel=8"
++#define CONFIG_ETHADDR                01:ab:cd:ef:fe:dc
++#define CONFIG_NETMASK          255.255.255.0
++#define CONFIG_IPADDR         10.0.0.110
++#define CONFIG_SERVERIP               10.0.0.1
++/*#define CONFIG_BOOTFILE     "elinos-lart" */
++#define CONFIG_BOOTCOMMAND    "nand load 0x32000000 0x34000 0x200000; bootm 0x32000000"
++
++#define CONFIG_DOS_PARTITION  1
++
++#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
++#define CONFIG_KGDB_BAUDRATE  115200          /* speed to run kgdb serial port */
++/* what's this ? it's not used anywhere */
++#define CONFIG_KGDB_SER_INDEX 1               /* which serial port to use */
++#endif
++
++/*
++ * Miscellaneous configurable options
++ */
++#define       CFG_LONGHELP                            /* undef to save memory         */
++#define       CFG_PROMPT              "QT2410 # "     /* Monitor Command Prompt       */
++#define       CFG_CBSIZE              256             /* Console I/O Buffer Size      */
++#define       CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
++#define       CFG_MAXARGS             64              /* max number of command args   */
++#define CFG_BARGSIZE          CFG_CBSIZE      /* Boot Argument Buffer Size    */
++
++#define CFG_MEMTEST_START     0x30000000      /* memtest works on     */
++#define CFG_MEMTEST_END               0x33F00000      /* 63 MB in DRAM        */
++
++#undef  CFG_CLKS_IN_HZ                /* everything, incl board info, in Hz */
++
++#define       CFG_LOAD_ADDR           0x33000000      /* default load address */
++
++/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
++/* it to wrap 100 times (total 1562500) to get 1 sec. */
++#define       CFG_HZ                  1562500
++
++/* valid baudrates */
++#define CFG_BAUDRATE_TABLE    { 9600, 19200, 38400, 57600, 115200 }
++
++/*-----------------------------------------------------------------------
++ * Stack sizes
++ *
++ * The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE      (128*1024)      /* regular stack */
++#ifdef CONFIG_USE_IRQ
++#define CONFIG_STACKSIZE_IRQ  (4*1024)        /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ  (4*1024)        /* FIQ stack */
++#endif
++
++#define CONFIG_USB_OHCI               1
++
++#define CONFIG_USB_DEVICE     1
++#define CONFIG_USB_TTY                1
++#define CFG_CONSOLE_IS_IN_ENV 1
++#define CONFIG_USBD_VENDORID          0x1457     /* Linux/NetChip */
++#define CONFIG_USBD_PRODUCTID_GSERIAL 0x5120    /* gserial */
++#define CONFIG_USBD_PRODUCTID_CDCACM  0x511d    /* CDC ACM */
++#define CONFIG_USBD_MANUFACTURER      "Armzone"
++#define CONFIG_USBD_PRODUCT_NAME      "QT2410 Bootloader " U_BOOT_VERSION
++#define CONFIG_EXTRA_ENV_SETTINGS     "usbtty=cdc_acm\0"
++#define CONFIG_USBD_DFU                       1
++#define CONFIG_USBD_DFU_XFER_SIZE     0x4000
++
++/*-----------------------------------------------------------------------
++ * Physical Memory Map
++ */
++#define CONFIG_NR_DRAM_BANKS  1          /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1          0x30000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE     0x04000000 /* 64 MB */
++#define PHYS_SDRAM_RES_SIZE   0x00200000 /* 2 MB for frame buffer */
++
++#define PHYS_FLASH_1          0x00000000 /* Flash Bank #1 */
++
++#define CFG_FLASH_BASE                PHYS_FLASH_1
++
++/*-----------------------------------------------------------------------
++ * FLASH and environment organization
++ */
++
++#define CONFIG_AMD_LV400      1       /* uncomment this if you have a LV400 flash */
++
++#define CFG_MAX_FLASH_BANKS   1       /* max number of memory banks */
++#define PHYS_FLASH_SIZE               0x00080000 /* 512KB */
++#define CFG_MAX_FLASH_SECT    (11)    /* max number of sectors on one chip */
++
++/* timeout values are in ticks */
++#define CFG_FLASH_ERASE_TOUT  (5*CFG_HZ) /* Timeout for Flash Erase */
++#define CFG_FLASH_WRITE_TOUT  (5*CFG_HZ) /* Timeout for Flash Write */
++
++#define       CFG_ENV_IS_IN_NAND      1
++#define CFG_ENV_SIZE          0x4000          /* 16k Total Size of Environment Sector */
++#define CFG_ENV_OFFSET_OOB    1               /* Location of ENV stored in block 0 OOB */
++
++#define NAND_MAX_CHIPS                1
++#define CFG_NAND_BASE         0x4e000000
++#define CFG_MAX_NAND_DEVICE   1
++
++#define CONFIG_MMC            1
++#define CFG_MMC_BASE          0xff000000
++
++#define CONFIG_EXT2           1
++
++/* FAT driver in u-boot is broken currently */
++#define CONFIG_FAT            1
++#define CONFIG_SUPPORT_VFAT
++
++#if 1
++/* JFFS2 driver */
++#define CONFIG_JFFS2_CMDLINE  1
++#define CONFIG_JFFS2_NAND     1
++#define CONFIG_JFFS2_NAND_DEV 0
++//#define CONFIG_JFFS2_NAND_OFF               0x634000
++//#define CONFIG_JFFS2_NAND_SIZE      0x39cc000
++#endif
++
++/* ATAG configuration */
++#define CONFIG_INITRD_TAG             1
++#define CONFIG_SETUP_MEMORY_TAGS      1
++#define CONFIG_CMDLINE_TAG            1
++
++#define CONFIG_DRIVER_S3C24X0_I2C     1
++#define CONFIG_HARD_I2C                       1
++#define CFG_I2C_SPEED                 400000  /* 400kHz according to PCF50606 data sheet */
++#define CFG_I2C_SLAVE                 0x7f
++
++#define CONFIG_VIDEO
++#define CONFIG_VIDEO_S3C2410
++#define CONFIG_CFB_CONSOLE
++#define CONFIG_VIDEO_LOGO
++#define CONFIG_SPLASH_SCREEN
++#define CFG_VIDEO_LOGO_MAX_SIZE               (640*480+1024+100) /* 100 = slack */
++#define CONFIG_VIDEO_BMP_GZIP
++#define CONFIG_VGA_AS_SINGLE_DEVICE
++#define CONFIG_UNZIP
++
++#define VIDEO_KBD_INIT_FCT     0
++#define VIDEO_TSTC_FCT         serial_tstc
++#define VIDEO_GETC_FCT         serial_getc
++
++#define LCD_VIDEO_ADDR         0x33d00000
++
++#define CONFIG_S3C2410_NAND_BBT       1
++
++#define MTDIDS_DEFAULT                "nand0=qt2410-nand"
++#define MTPARTS_DEFAULT               "qt2410-nand:192k(u-boot),8k(u-boot_env),2M(kernel),2M(splash),-(jffs2)"
++
++#endif        /* __CONFIG_H */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-arm920_s3c2410_irq_demux.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-arm920_s3c2410_irq_demux.patch
new file mode 100644 (file)
index 0000000..b39a268
--- /dev/null
@@ -0,0 +1,56 @@
+This patch adds a IRQ demultiplexer callback to the arm920 cpu core code,
+plus a stub implementation of it for the S3C2410.
+
+Index: u-boot.git/cpu/arm920t/interrupts.c
+===================================================================
+--- u-boot.git.orig/cpu/arm920t/interrupts.c   2007-02-05 22:49:11.000000000 +0100
++++ u-boot.git/cpu/arm920t/interrupts.c        2007-02-05 23:19:01.000000000 +0100
+@@ -161,11 +161,16 @@
+ void do_irq (struct pt_regs *pt_regs)
+ {
+-#if defined (CONFIG_USE_IRQ) && defined (CONFIG_ARCH_INTEGRATOR)
++#if defined (CONFIG_USE_IRQ)
++#if defined (ARM920_IRQ_CALLBACK)
++      ARM920_IRQ_CALLBACK();
++      return;
++#elif defined (CONFIG_ARCH_INTEGRATOR)
+       /* ASSUMED to be a timer interrupt  */
+       /* Just clear it - count handled in */
+       /* integratorap.c                   */
+       *(volatile ulong *)(CFG_TIMERBASE + 0x0C) = 0;
++#endif /* ARCH_INTEGRATOR */
+ #else
+       printf ("interrupt request\n");
+       show_regs (pt_regs);
+Index: u-boot.git/cpu/arm920t/s3c24x0/interrupts.c
+===================================================================
+--- u-boot.git.orig/cpu/arm920t/s3c24x0/interrupts.c   2007-02-05 22:49:11.000000000 +0100
++++ u-boot.git/cpu/arm920t/s3c24x0/interrupts.c        2007-02-05 23:21:35.000000000 +0100
+@@ -216,4 +216,13 @@
+       /*NOTREACHED*/
+ }
++#ifdef CONFIG_USE_IRQ
++void s3c2410_irq(void)
++{
++      S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
++      u_int32_t intpnd = irq->INTPND;
++
++}
++#endif /* USE_IRQ */
++
+ #endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) */
+Index: u-boot.git/include/common.h
+===================================================================
+--- u-boot.git.orig/include/common.h   2007-02-05 22:49:11.000000000 +0100
++++ u-boot.git/include/common.h        2007-02-05 23:19:01.000000000 +0100
+@@ -452,6 +452,8 @@
+ ulong get_PCI_freq (void);
+ #endif
+ #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_LH7A40X)
++void  s3c2410_irq(void);
++#define ARM920_IRQ_CALLBACK s3c2410_irq
+ ulong get_FCLK (void);
+ ulong get_HCLK (void);
+ ulong get_PCLK (void);
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-arm920t-gd_in_irq.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-arm920t-gd_in_irq.patch
new file mode 100644 (file)
index 0000000..b3d7bc1
--- /dev/null
@@ -0,0 +1,28 @@
+This patch allows us to use the 'gd' pointer (and thus environment
+and everything else associated with it) from interrupt context on
+arm920t.
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+
+Index: u-boot/cpu/arm920t/start.S
+===================================================================
+--- u-boot.orig/cpu/arm920t/start.S    2007-02-24 02:35:38.000000000 +0100
++++ u-boot/cpu/arm920t/start.S 2007-02-24 02:36:01.000000000 +0100
+@@ -474,12 +474,12 @@
+       .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
++      add     r7, sp, #S_PC
++      stmdb   r7, {sp, lr}^                   @ Calling SP, LR
++      str     lr, [r7, #0]                    @ Save calling PC
+       mrs     r6, spsr
+-      str     r6, [r8, #4]                    @ Save CPSR
+-      str     r0, [r8, #8]                    @ Save OLD_R0
++      str     r6, [r7, #4]                    @ Save CPSR
++      str     r0, [r7, #8]                    @ Save OLD_R0
+       mov     r0, sp
+       .endm
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-bbt-quiet.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-bbt-quiet.patch
new file mode 100644 (file)
index 0000000..9b1febe
--- /dev/null
@@ -0,0 +1,43 @@
+This patch makes the u-boot NAND BBT code a bit more quiet
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+
+Index: u-boot/drivers/nand/nand_bbt.c
+===================================================================
+--- u-boot.orig/drivers/nand/nand_bbt.c        2007-02-16 23:54:02.000000000 +0100
++++ u-boot/drivers/nand/nand_bbt.c     2007-02-16 23:54:05.000000000 +0100
+@@ -157,10 +157,6 @@
+                                       this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
+                                       continue;
+                               }
+-                              /* Leave it for now, if its matured we can move this
+-                               * message to MTD_DEBUG_LEVEL0 */
+-                              printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
+-                                      ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
+                               /* Factory marked bad or worn out ? */
+                               if (tmp == 0)
+                                       this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
+@@ -229,14 +225,12 @@
+       if (td->options & NAND_BBT_VERSION) {
+               nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
+               td->version[0] = buf[mtd->oobblock + td->veroffs];
+-              printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
+       }
+       /* Read the mirror version, if available */
+       if (md && (md->options & NAND_BBT_VERSION)) {
+               nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
+               md->version[0] = buf[mtd->oobblock + md->veroffs];
+-              printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
+       }
+       return 1;
+@@ -374,8 +368,6 @@
+       for (i = 0; i < chips; i++) {
+               if (td->pages[i] == -1)
+                       printk (KERN_WARNING "Bad block table not found for chip %d\n", i);
+-              else
+-                      printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]);
+       }
+       return 0;
+ }
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-cmd_s3c2410.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-cmd_s3c2410.patch
new file mode 100644 (file)
index 0000000..993ef4f
--- /dev/null
@@ -0,0 +1,175 @@
+This patch adds a new 's3c2410' command which currently supports 's3c2410 speed
+{set,get,list} and thus allows dynamic change of the CPU clock.
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+
+Index: u-boot/cpu/arm920t/s3c24x0/Makefile
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/Makefile   2007-02-24 15:14:00.000000000 +0100
++++ u-boot/cpu/arm920t/s3c24x0/Makefile        2007-02-24 15:21:02.000000000 +0100
+@@ -26,7 +26,7 @@
+ LIB   = $(obj)lib$(SOC).a
+ COBJS = i2c.o interrupts.o serial.o speed.o \
+-        usb_ohci.o nand_read.o nand.o
++        usb_ohci.o nand_read.o nand.o cmd_s3c2410.o
+ SRCS  := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+ OBJS  := $(addprefix $(obj),$(SOBJS) $(COBJS))
+Index: u-boot/cpu/arm920t/s3c24x0/cmd_s3c2410.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ u-boot/cpu/arm920t/s3c24x0/cmd_s3c2410.c   2007-02-24 15:22:17.000000000 +0100
+@@ -0,0 +1,152 @@
++/*
++ * (C) Copyright 2006 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * 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
++ */
++
++/*
++ * Boot support
++ */
++#include <common.h>
++#include <command.h>
++#include <net.h>              /* for print_IPaddr */
++#include <s3c2410.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#if (CONFIG_COMMANDS & CFG_CMD_BDI)
++
++#define ARRAY_SIZE(x)           (sizeof(x) / sizeof((x)[0]))
++#define MHZ   1000000
++
++static void print_cpu_speed(void)
++{
++      printf("FCLK = %u MHz, HCLK = %u MHz, PCLK = %u MHz\n",
++              get_FCLK()/MHZ, get_HCLK()/MHZ, get_PCLK()/MHZ);
++}
++
++struct s3c2410_pll_speed {
++      u_int16_t       mhz;
++      u_int32_t       mpllcon;
++      u_int32_t       clkdivn;
++};
++
++#define CLKDIVN_1_1_1 0x00
++#define CLKDIVN_1_2_2 0x02
++#define CLKDIVN_1_2_4 0x03
++#define CLKDIVN_1_4_4 0x04
++
++static const struct s3c2410_pll_speed pll_configs[] = {
++      {
++              .mhz = 50,
++              .mpllcon = ((0x5c << 12) + (0x4 << 4) + 0x2),
++              .clkdivn = CLKDIVN_1_1_1,
++      },
++      {
++              .mhz = 101,
++              .mpllcon = ((0x7f << 12) + (0x2 << 4) + 0x2),
++              .clkdivn = CLKDIVN_1_2_2,
++      },
++      {
++              .mhz = 202,
++              .mpllcon = ((0x90 << 12) + (0x7 << 4) + 0x0),
++              .clkdivn = CLKDIVN_1_2_4,
++      },
++      {
++              .mhz = 266,
++              .mpllcon = ((0x7d << 12) + (0x1 << 4) + 0x1),
++              .clkdivn = CLKDIVN_1_2_4,
++      },
++};
++
++static void list_cpu_speeds(void)
++{
++      int i;
++      for (i = 0; i < ARRAY_SIZE(pll_configs); i++)
++              printf("%u MHz\n", pll_configs[i].mhz);
++}
++
++static int reconfig_mpll(u_int16_t mhz)
++{
++      S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(pll_configs); i++) {
++              if (pll_configs[i].mhz == mhz) {
++                      /* to reduce PLL lock time, adjust the LOCKTIME register */
++                      clk_power->LOCKTIME = 0xFFFFFF;
++
++                      /* configure MPLL */
++                      clk_power->MPLLCON = pll_configs[i].mpllcon;
++                      clk_power->UPLLCON = ((0x78 << 12) + (0x2 << 4) + 0x3),
++                      clk_power->CLKDIVN = pll_configs[i].clkdivn;
++
++                      /* If we changed the speed, we need to re-configure
++                       * the serial baud rate generator */
++                      serial_setbrg();
++                      return 0;
++              }
++      }
++      return -1;
++}
++
++int do_s3c2410 ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++      if (!strcmp(argv[1], "speed")) {
++              if (argc < 2)
++                      goto out_help;
++              if (!strcmp(argv[2], "get"))
++                      print_cpu_speed();
++              else if (!strcmp(argv[2], "list"))
++                      list_cpu_speeds();
++              else if (!strcmp(argv[2], "set")) {
++                      unsigned long mhz;
++                      if (argc < 3)
++                              goto out_help;
++
++                      mhz = simple_strtoul(argv[3], NULL, 10);
++
++                      if (reconfig_mpll(mhz) < 0)
++                              printf("error, speed %uMHz unknown\n", mhz);
++                      else
++                              print_cpu_speed();
++              } else
++                      goto out_help;
++      } else {
++out_help:
++              printf("Usage:\n%s\n", cmdtp->usage);
++              return 1;
++      }
++
++      return 0;
++}
++
++/* -------------------------------------------------------------------- */
++
++
++U_BOOT_CMD(
++      s3c2410,        4,      1,      do_s3c2410,
++      "s3c2410 - SoC  specific commands\n",
++      "speed get - display current PLL speed config\n"
++      "s3c2410 speed list - display supporte PLL speed configs\n"
++      "s3c2410 speed set - set PLL speed\n"
++);
++
++#endif
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-cramfs_but_no_jffs2.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-cramfs_but_no_jffs2.patch
new file mode 100644 (file)
index 0000000..349b836
--- /dev/null
@@ -0,0 +1,41 @@
+Fix building with CRAMFS but not JFFS2 support
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+
+Index: u-boot/fs/cramfs/cramfs.c
+===================================================================
+--- u-boot.orig/fs/cramfs/cramfs.c     2007-02-17 11:46:26.000000000 +0100
++++ u-boot/fs/cramfs/cramfs.c  2007-02-17 11:54:36.000000000 +0100
+@@ -27,7 +27,7 @@
+ #include <common.h>
+ #include <malloc.h>
+-#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
++#if (CONFIG_COMMANDS & CFG_CMD_CRAMFS)
+ #include <asm/byteorder.h>
+ #include <linux/stat.h>
+Index: u-boot/common/cmd_jffs2.c
+===================================================================
+--- u-boot.orig/common/cmd_jffs2.c     2007-02-17 11:47:51.000000000 +0100
++++ u-boot/common/cmd_jffs2.c  2007-02-17 14:08:25.000000000 +0100
+@@ -170,10 +170,19 @@
+ static struct mtd_device *current_dev = NULL;
+ static u8 current_partnum = 0;
++#ifdef CFG_CMD_CRAMFS
+ extern int cramfs_check (struct part_info *info);
+ extern int cramfs_load (char *loadoffset, struct part_info *info, char *filename);
+ extern int cramfs_ls (struct part_info *info, char *filename);
+ extern int cramfs_info (struct part_info *info);
++#else
++/* defining empty macros for function names is ugly but avoids ifdef clutter
++ * all over the code */
++#define cramfs_check(x)               (0)
++#define cramfs_load(x,y,z)    (-1)
++#define cramfs_ls(x,y)                (0)
++#define cramfs_info(x)                (0)
++#endif
+ static struct part_info* jffs2_part_info(struct mtd_device *dev, unsigned int part_num);
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-dfu.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-dfu.patch
new file mode 100644 (file)
index 0000000..1122f48
--- /dev/null
@@ -0,0 +1,2081 @@
+Index: u-boot/drivers/usbdcore_ep0.c
+===================================================================
+--- u-boot.orig/drivers/usbdcore_ep0.c
++++ u-boot/drivers/usbdcore_ep0.c
+@@ -42,10 +42,15 @@
+  */
+ #include <common.h>
++DECLARE_GLOBAL_DATA_PTR;
+ #if defined(CONFIG_USB_DEVICE)
+ #include "usbdcore.h"
++#ifdef CONFIG_USBD_DFU
++#include <usb_dfu.h>
++#endif
++
+ #if 0
+ #define dbg_ep0(lvl,fmt,args...) serial_printf("[%s] %s:%d: "fmt"\n",__FILE__,__FUNCTION__,__LINE__,##args)
+ #else
+@@ -213,7 +218,7 @@
+                       urb->buffer = device_descriptor;
+                       urb->actual_length = MIN(sizeof(*device_descriptor), max);
+               }
+-              /*dbg_ep0(3, "copied device configuration, actual_length: %x", urb->actual_length); */
++              dbg_ep0(3, "using device configuration, actual_length: %x", urb->actual_length);
+               break;
+       case USB_DESCRIPTOR_TYPE_CONFIGURATION:
+@@ -267,7 +272,24 @@
+               return -1;
+       case USB_DESCRIPTOR_TYPE_ENDPOINT:
+               return -1;
++      /* This really means "Class Specific Descriptor #1 == USB_DT_DFU */
+       case USB_DESCRIPTOR_TYPE_HID:
++#ifdef CONFIG_USBD_DFU
++              {
++                      int bNumInterface =
++                              le16_to_cpu(urb->device_request.wIndex);
++
++                      /* In runtime mode, we only respond to the DFU INTERFACE,
++                       * whereas in DFU mode, we respond for all intrfaces */
++                      if (device->dfu_state != DFU_STATE_appIDLE &&
++                          device->dfu_state != DFU_STATE_appDETACH ||
++                          bNumInterface == CONFIG_USBD_DFU_INTERFACE) {
++                              urb->buffer = &device->dfu_cfg_desc->func_dfu;
++                              urb->actual_length = sizeof(struct usb_dfu_func_descriptor);
++                      } else
++                              return -1;
++              }
++#else /* CONFIG_USBD_DFU */
+               {
+                       return -1;      /* unsupported at this time */
+ #if 0
+@@ -294,6 +316,7 @@
+                                    max);
+ #endif
+               }
++#endif /* CONFIG_USBD_DFU */
+               break;
+       case USB_DESCRIPTOR_TYPE_REPORT:
+               {
+@@ -388,6 +411,24 @@
+                le16_to_cpu (request->wLength),
+                USBD_DEVICE_REQUESTS (request->bRequest));
++#ifdef CONFIG_USBD_DFU
++      if ((request->bmRequestType & 0x3f) == USB_TYPE_DFU &&
++           (device->dfu_state != DFU_STATE_appIDLE ||
++            le16_to_cpu(request->wIndex) == CONFIG_USBD_DFU_INTERFACE)) {
++              int rc = dfu_ep0_handler(urb);
++              switch (rc) {
++              case DFU_EP0_NONE:
++              case DFU_EP0_UNHANDLED:
++                      break;
++              case DFU_EP0_ZLP:
++              case DFU_EP0_DATA:
++                      return 0;
++              case DFU_EP0_STALL:
++                      return -1;
++              }
++      }
++#endif /* CONFIG_USB_DFU */
++
+       /* handle USB Standard Request (c.f. USB Spec table 9-2) */
+       if ((request->bmRequestType & USB_REQ_TYPE_MASK) != 0) {
+               if (device->device_state <= STATE_CONFIGURED)
+@@ -570,7 +611,8 @@
+                       device->interface = le16_to_cpu (request->wIndex);
+                       device->alternate = le16_to_cpu (request->wValue);
+                       /*dbg_ep0(2, "set interface: %d alternate: %d", device->interface, device->alternate); */
+-                      serial_printf ("DEVICE_SET_INTERFACE.. event?\n");
++                      usbd_device_event_irq(device, DEVICE_SET_INTERFACE,
++                                              (request->wIndex << 16 | request->wValue));
+                       return 0;
+               case USB_REQ_GET_STATUS:
+Index: u-boot/drivers/usbdfu.c
+===================================================================
+--- /dev/null
++++ u-boot/drivers/usbdfu.c
+@@ -0,0 +1,1069 @@
++/*
++ * (C) 2007 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * based on existing SAM7DFU code from OpenPCD:
++ * (C) Copyright 2006 by Harald Welte <hwelte@hmw-consulting.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
++ *
++ * TODO:
++ * - make NAND support reasonably self-contained and put in apropriate
++ *   ifdefs
++ * - add some means of synchronization, i.e. block commandline access
++ *   while DFU transfer is in progress, and return to commandline once
++ *   we're finished
++ * - add VERIFY support after writing to flash
++ * - sanely free() resources allocated during first uppload/download
++ *   request when aborting
++ * - sanely free resources when another alternate interface is selected
++ *
++ * Maybe:
++ * - add something like uImage or some other header that provides CRC
++ *   checking?
++ * - make 'dnstate' attached to 'struct usb_device_instance'
++ */
++
++#include <config.h>
++#if defined(CONFIG_USBD_DFU)
++
++#include <common.h>
++DECLARE_GLOBAL_DATA_PTR;
++
++#include <malloc.h>
++#include <linux/types.h>
++#include <linux/list.h>
++#include <asm/errno.h>
++#include <usbdcore.h>
++#include <usb_dfu.h>
++#include <usb_dfu_descriptors.h>
++#include <usb_dfu_trailer.h>
++
++#include <nand.h>
++#include <jffs2/load_kernel.h>
++int mtdparts_init(void);
++extern struct list_head devices;
++
++#include "usbdcore_s3c2410.h"
++#include "usbtty.h"                   /* for STR_* defs */
++
++#define RET_NOTHING   0
++#define RET_ZLP               1
++#define RET_STALL     2
++
++volatile enum dfu_state *system_dfu_state; /* for 3rd parties */
++
++
++struct dnload_state {
++      nand_info_t *nand;
++      struct part_info *part;
++      unsigned int part_net_size;     /* net sizee (excl. bad blocks) of part */
++
++      nand_erase_options_t erase_opts;
++      nand_write_options_t write_opts;
++      nand_read_options_t read_opts;
++
++      unsigned char *ptr;     /* pointer to next empty byte in buffer */
++      unsigned int off;       /* offset of current erase page in flash chip */
++      unsigned char *buf;     /* pointer to allocated erase page buffer */
++
++      /* unless doing an atomic transfer, we use the static buffer below.
++       * This saves us from having to clean up dynamic allications in the
++       * various error paths of the code.  Also, it will always work, no
++       * matter what the memory situation is. */
++      unsigned char _buf[0x20000];    /* FIXME: depends flash page size */
++};
++
++static struct dnload_state _dnstate;
++
++static int dfu_trailer_matching(const struct uboot_dfu_trailer *trailer)
++{
++      if (trailer->magic != UBOOT_DFU_TRAILER_MAGIC ||
++          trailer->version != UBOOT_DFU_TRAILER_V1 ||
++          trailer->vendor != CONFIG_USBD_VENDORID ||
++          (trailer->product != CONFIG_USBD_PRODUCTID_CDCACM &&
++           trailer->product != CONFIG_USBD_PRODUCTID_GSERIAL))
++              return 0;
++#ifdef CONFIG_REVISION_TAG
++      if (trailer->revision != get_board_rev())
++              return 0;
++#endif
++
++      return 1;
++}
++
++static struct part_info *get_partition_nand(int idx)
++{
++      struct mtd_device *dev;
++      struct part_info *part;
++      struct list_head *pentry;
++      int i;
++
++      if (mtdparts_init())
++              return NULL;
++      if (list_empty(&devices))
++              return NULL;
++
++      dev = list_entry(devices.next, struct mtd_device, link);
++      i = 0;
++      list_for_each(pentry, &dev->parts) {
++              if (i == idx)  {
++                      part = list_entry(pentry, struct part_info, link);
++                      return part;
++              }
++              i++;
++      }
++
++      return NULL;
++}
++
++#define LOAD_ADDR ((unsigned char *)0x32000000)
++
++static int initialize_ds_nand(struct usb_device_instance *dev, struct dnload_state *ds)
++{
++      ds->part = get_partition_nand(dev->alternate - 1);
++      if (!ds->part) {
++              printf("DFU: unable to find partition %u\b", dev->alternate-1);
++                      dev->dfu_state = DFU_STATE_dfuERROR;
++              dev->dfu_status = DFU_STATUS_errADDRESS;
++              return RET_STALL;
++      }
++      ds->nand = &nand_info[ds->part->dev->id->num];
++      ds->off = ds->part->offset;
++      ds->part_net_size = nand_net_part_size(ds->part);
++
++      if (ds->nand->erasesize > sizeof(ds->_buf)) {
++              printf("*** Warning - NAND ERASESIZE bigger than static buffer\n");
++              ds->buf = malloc(ds->nand->erasesize);
++              if (!ds->buf) {
++                      printf("DFU: can't allocate %u bytes\n", ds->nand->erasesize);
++                      dev->dfu_state = DFU_STATE_dfuERROR;
++                      dev->dfu_status = DFU_STATUS_errADDRESS;
++                      return RET_STALL;
++              }
++      } else
++              ds->buf = ds->_buf;
++
++      ds->ptr = ds->buf;
++
++      memset(&ds->read_opts, 0, sizeof(ds->read_opts));
++
++      memset(&ds->erase_opts, 0, sizeof(ds->erase_opts));
++      ds->erase_opts.quiet = 1;
++      /* FIXME: do this more dynamic */
++      if (!strcmp(ds->part->name, "rootfs"))
++              ds->erase_opts.jffs2 = 1;
++
++      memset(&ds->write_opts, 0, sizeof(ds->write_opts));
++      ds->write_opts.pad = 1;
++      ds->write_opts.blockalign = 1;
++      ds->write_opts.quiet = 1;
++
++      debug("initialize_ds_nand(dev=%p, ds=%p): ", dev, ds);
++      debug("nand=%p, ptr=%p, buf=%p, off=0x%x\n", ds->nand, ds->ptr, ds->buf, ds->off);
++
++      return RET_NOTHING;
++}
++
++static int erase_flash_verify_nand(struct urb *urb, struct dnload_state *ds,
++                                 unsigned long erasesize, unsigned long size)
++{
++      struct usb_device_instance *dev = urb->device;
++      int rc;
++
++      debug("erase_flash_verify_nand(urb=%p, ds=%p, erase=0x%x size=0x%x)\n",
++              urb, ds, erasesize, size);
++
++      if (erasesize == ds->nand->erasesize) {
++              /* we're only writing a single block and need to
++               * do bad block skipping / offset adjustments our own */
++              while (ds->nand->block_isbad(ds->nand, ds->off)) {
++                      debug("SKIP_ONE_BLOCK(0x%08x)!!\n", ds->off);
++                      ds->off += ds->nand->erasesize;
++              }
++      }
++
++      /* we have finished one eraseblock, flash it */
++      ds->erase_opts.offset = ds->off;
++      ds->erase_opts.length = erasesize;
++      debug("Erasing 0x%x bytes @ offset 0x%x (jffs=%u)\n",
++              ds->erase_opts.length, ds->erase_opts.offset,
++              ds->erase_opts.jffs2);
++      rc = nand_erase_opts(ds->nand, &ds->erase_opts);
++      if (rc) {
++              debug("Error erasing\n");
++              dev->dfu_state = DFU_STATE_dfuERROR;
++              dev->dfu_status = DFU_STATUS_errERASE;
++              return RET_STALL;
++      }
++
++      ds->write_opts.buffer = ds->buf;
++      ds->write_opts.length = size;
++      ds->write_opts.offset = ds->off;
++      debug("Writing 0x%x bytes @ offset 0x%x\n", size, ds->off);
++      rc = nand_write_opts(ds->nand, &ds->write_opts);
++      if (rc) {
++              debug("Error writing\n");
++              dev->dfu_state = DFU_STATE_dfuERROR;
++              dev->dfu_status = DFU_STATUS_errWRITE;
++              return RET_STALL;
++      }
++
++      ds->off += size;
++      ds->ptr = ds->buf;
++
++      /* FIXME: implement verify! */
++      return RET_NOTHING;
++}
++
++static int erase_tail_clean_nand(struct urb *urb, struct dnload_state *ds)
++{
++      struct usb_device_instance *dev = urb->device;
++      int rc;
++
++      ds->erase_opts.offset = ds->off;
++      ds->erase_opts.length = ds->part->size-ds->off;
++      debug("Erasing 0x%x bytes @ offset 0x%x (jffs=%u)\n",
++              ds->erase_opts.length, ds->erase_opts.offset,
++              ds->erase_opts.jffs2);
++      rc = nand_erase_opts(ds->nand, &ds->erase_opts);
++      if (rc) {
++              debug("Error erasing\n");
++              dev->dfu_state = DFU_STATE_dfuERROR;
++              dev->dfu_status = DFU_STATUS_errERASE;
++              return RET_STALL;
++      }
++
++      ds->off += ds->part->size; /* for consistency */
++
++      return RET_NOTHING;
++}
++
++/* Read the next erase blcok from NAND into buffer */
++static int read_next_nand(struct urb *urb, struct dnload_state *ds)
++{
++      struct usb_device_instance *dev = urb->device;
++      int rc;
++
++      ds->read_opts.buffer = ds->buf;
++      ds->read_opts.length = ds->nand->erasesize;
++      ds->read_opts.offset = ds->off;
++      ds->read_opts.quiet = 1;
++
++      debug("Reading 0x%x@0x%x to 0x%08p\n", ds->nand->erasesize,
++              ds->off, ds->buf);
++      rc = nand_read_opts(ds->nand, &ds->read_opts);
++      if (rc) {
++              debug("Error reading\n");
++              dev->dfu_state = DFU_STATE_dfuERROR;
++              dev->dfu_status = DFU_STATUS_errWRITE;
++              return RET_STALL;
++      }
++      ds->off += ds->nand->erasesize;
++      ds->ptr = ds->buf;
++
++      return RET_NOTHING;
++}
++
++
++static int handle_dnload(struct urb *urb, u_int16_t val, u_int16_t len, int first)
++{
++      struct usb_device_instance *dev = urb->device;
++      struct dnload_state *ds = &_dnstate;
++      unsigned int actual_len = len;
++      unsigned int remain_len;
++      unsigned long size;
++      int rc;
++
++      debug("download(len=%u, first=%u) ", len, first);
++
++      if (len > CONFIG_USBD_DFU_XFER_SIZE) {
++              /* Too big. Not that we'd really care, but it's a
++               * DFU protocol violation */
++              debug("length exceeds flash page size ");
++              dev->dfu_state = DFU_STATE_dfuERROR;
++              dev->dfu_status = DFU_STATUS_errADDRESS;
++              return RET_STALL;
++      }
++
++      if (first) {
++              /* Make sure that we have a valid mtd partition table */
++              char *mtdp = getenv("mtdparts");
++              if (!mtdp)
++                      run_command("dynpart", 0);
++      }
++
++      if (len == 0) {
++              debug("zero-size write -> MANIFEST_SYNC ");
++              dev->dfu_state = DFU_STATE_dfuMANIFEST_SYNC;
++
++              /* cleanup */
++              switch (dev->alternate) {
++                      char buf[12];
++              case 0:
++                      sprintf(buf, "%lx", ds->ptr - ds->buf);
++                      setenv("filesize", buf);
++                      ds->ptr = ds->buf;
++                      break;
++              case 1:
++                      if (ds->ptr >
++                          ds->buf + sizeof(struct uboot_dfu_trailer)) {
++                              struct uboot_dfu_trailer trailer;
++                              dfu_trailer_mirror(&trailer, ds->ptr);
++                              if (!dfu_trailer_matching(&trailer)) {
++                                      printf("DFU TRAILER NOT OK\n");
++                                      dev->dfu_state = DFU_STATE_dfuERROR;
++                                      dev->dfu_status = DFU_STATUS_errTARGET;
++                                      return RET_STALL;
++                              }
++
++                              rc = erase_flash_verify_nand(urb, ds,
++                                                      ds->part->size,
++                                                      ds->part_net_size);
++                              /* re-write dynenv marker in OOB */
++                              run_command("dynenv set u-boot_env", 0);
++                      }
++                      ds->nand = NULL;
++                      free(ds->buf);
++                      ds->ptr = ds->buf = ds->_buf;
++                      break;
++              default:
++                      rc = 0;
++                      if (ds->ptr > ds->buf)
++                              rc = erase_flash_verify_nand(urb, ds,
++                                                      ds->nand->erasesize,
++                                                      ds->nand->erasesize);
++                      /* rootfs partition */
++                      if (!rc && dev->alternate == 5)
++                              rc = erase_tail_clean_nand(urb, ds);
++
++                      ds->nand = NULL;
++                      break;
++              }
++
++              return RET_ZLP;
++      }
++
++      if (urb->actual_length != len) {
++              debug("urb->actual_length(%u) != len(%u) ?!? ",
++                      urb->actual_length, len);
++              dev->dfu_state = DFU_STATE_dfuERROR;
++              dev->dfu_status = DFU_STATUS_errADDRESS;
++              return RET_STALL;
++      }
++
++      if (first && ds->buf && ds->buf != ds->_buf && ds->buf != LOAD_ADDR) {
++              free(ds->buf);
++              ds->buf = ds->_buf;
++      }
++
++      switch (dev->alternate) {
++      case 0:
++              if (first) {
++                      printf("Starting DFU DOWNLOAD to RAM (0x%08p)\n",
++                              LOAD_ADDR);
++                      ds->buf = LOAD_ADDR;
++                      ds->ptr = ds->buf;
++              }
++
++              memcpy(ds->ptr, urb->buffer, len);
++              ds->ptr += len;
++              break;
++      case 1:
++              if (first) {
++                      rc = initialize_ds_nand(dev, ds);
++                      if (rc)
++                              return rc;
++                      ds->buf = malloc(ds->part_net_size);
++                      if (!ds->buf) {
++                              printf("No memory for atomic buffer!!\n");
++                              dev->dfu_state = DFU_STATE_dfuERROR;
++                              dev->dfu_status = DFU_STATUS_errUNKNOWN;
++                              return RET_STALL;
++                      }
++                      ds->ptr = ds->buf;
++                      printf("Starting Atomic DFU DOWNLOAD to partition '%s'\n",
++                              ds->part->name);
++              }
++
++              remain_len = (ds->buf + ds->part_net_size) - ds->ptr;
++              if (remain_len < len) {
++                      len = remain_len;
++                      printf("End of write exceeds partition end\n");
++                      dev->dfu_state = DFU_STATE_dfuERROR;
++                      dev->dfu_status = DFU_STATUS_errADDRESS;
++                      return RET_STALL;
++              }
++              memcpy(ds->ptr, urb->buffer, len);
++              ds->ptr += len;
++              break;
++      default:
++              if (first) {
++                      rc = initialize_ds_nand(dev, ds);
++                      if (rc)
++                              return rc;
++                      printf("Starting DFU DOWNLOAD to partition '%s'\n",
++                              ds->part->name);
++              }
++
++              size = ds->nand->erasesize;
++              remain_len = ds->buf + size - ds->ptr;
++              if (remain_len < len)
++                      actual_len = remain_len;
++
++              memcpy(ds->ptr, urb->buffer, actual_len);
++              ds->ptr += actual_len;
++
++              /* check partition end */
++              if (ds->off + (ds->ptr - ds->buf) > ds->part->offset + ds->part->size) {
++                      printf("End of write exceeds partition end\n");
++                      dev->dfu_state = DFU_STATE_dfuERROR;
++                      dev->dfu_status = DFU_STATUS_errADDRESS;
++                      return RET_STALL;
++              }
++
++              if (ds->ptr >= ds->buf + size) {
++                      rc = erase_flash_verify_nand(urb, ds,
++                                                   ds->nand->erasesize,
++                                                   ds->nand->erasesize);
++                      if (rc)
++                              return rc;
++                      /* copy remainder of data into buffer */
++                      memcpy(ds->ptr, urb->buffer + actual_len, len - actual_len);
++                      ds->ptr += (len - actual_len);
++              }
++              break;
++      }
++
++      return RET_ZLP;
++}
++
++static int handle_upload(struct urb *urb, u_int16_t val, u_int16_t len, int first)
++{
++      struct usb_device_instance *dev = urb->device;
++      struct dnload_state *ds = &_dnstate;
++      unsigned int remain;
++      int rc;
++
++      debug("upload(val=0x%02x, len=%u, first=%u) ", val, len, first);
++
++      if (len > CONFIG_USBD_DFU_XFER_SIZE) {
++              /* Too big */
++              dev->dfu_state = DFU_STATE_dfuERROR;
++              dev->dfu_status = DFU_STATUS_errADDRESS;
++              //udc_ep0_send_stall();
++              debug("Error: Transfer size > CONFIG_USBD_DFU_XFER_SIZE ");
++              return -EINVAL;
++      }
++
++      switch (dev->alternate) {
++      case 0:
++              if (first) {
++                      printf("Starting DFU Upload of RAM (0x%08p)\n",
++                              LOAD_ADDR);
++                      ds->ptr = ds->buf;
++              }
++
++              /* FIXME: end at some more dynamic point */
++              if (ds->ptr + len > LOAD_ADDR + 0x200000)
++                      len = (LOAD_ADDR + 0x200000) - ds->ptr;
++
++              urb->buffer = ds->ptr;
++              urb->actual_length = len;
++              ds->ptr += len;
++              break;
++      default:
++              if (first) {
++                      rc = initialize_ds_nand(dev, ds);
++                      if (rc)
++                              return -EINVAL;
++                      printf("Starting DFU Upload of partition '%s'\n",
++                              ds->part->name);
++                      rc = read_next_nand(urb, ds);
++                      if (rc)
++                              return -EINVAL;
++              }
++
++              if (len > ds->nand->erasesize) {
++                      printf("We don't support transfers bigger than %u\n",
++                              ds->nand->erasesize);
++                      len = ds->nand->erasesize;
++              }
++
++              remain = ds->nand->erasesize - (ds->ptr - ds->buf);
++              if (len < remain)
++                      remain = len;
++
++              debug("copying %u bytes ", remain);
++              urb->buffer = ds->ptr;
++              ds->ptr += remain;
++              urb->actual_length = remain;
++
++              if (ds->ptr >= ds->buf + ds->nand->erasesize &&
++                  ds->off < ds->part->offset + ds->part->size) {
++                      rc = read_next_nand(urb, ds);
++                      if (rc)
++                              return -EINVAL;
++                      if (len > remain) {
++                              debug("copying another %u bytes ", len - remain);
++                              memcpy(urb->buffer + remain, ds->ptr, len - remain);
++                              ds->ptr += (len - remain);
++                              urb->actual_length += (len - remain);
++                      }
++              }
++              break;
++      }
++
++      debug("returning len=%u\n", len);
++      return len;
++}
++
++static void handle_getstatus(struct urb *urb, int max)
++{
++      struct usb_device_instance *dev = urb->device;
++      struct dfu_status *dstat = (struct dfu_status *) urb->buffer;
++
++      debug("getstatus ");
++
++      if (!urb->buffer || urb->buffer_length < sizeof(*dstat)) {
++              debug("invalid urb! ");
++              return;
++      }
++
++      switch (dev->dfu_state) {
++      case DFU_STATE_dfuDNLOAD_SYNC:
++      case DFU_STATE_dfuDNBUSY:
++#if 0
++              if (fsr & AT91C_MC_PROGE) {
++                      debug("errPROG ");
++                      dev->dfu_status = DFU_STATUS_errPROG;
++                      dev->dfu_state = DFU_STATE_dfuERROR;
++              } else if (fsr & AT91C_MC_LOCKE) {
++                      debug("errWRITE ");
++                      dev->dfu_status = DFU_STATUS_errWRITE;
++                      dev->dfu_state = DFU_STATE_dfuERROR;
++              } else if (fsr & AT91C_MC_FRDY) {
++#endif
++                      debug("DNLOAD_IDLE ");
++                      dev->dfu_state = DFU_STATE_dfuDNLOAD_IDLE;
++#if 0
++              } else {
++                      debug("DNBUSY ");
++                      dev->dfu_state = DFU_STATE_dfuDNBUSY;
++              }
++#endif
++              break;
++      case DFU_STATE_dfuMANIFEST_SYNC:
++              break;
++      default:
++              //return;
++              break;
++      }
++
++      /* send status response */
++      dstat->bStatus = dev->dfu_status;
++      dstat->bState = dev->dfu_state;
++      dstat->iString = 0;
++      /* FIXME: set dstat->bwPollTimeout */
++      urb->actual_length = MIN(sizeof(*dstat), max);
++
++      /* we don't need to explicitly send data here, will
++       * be done by the original caller! */
++}
++
++static void handle_getstate(struct urb *urb, int max)
++{
++      debug("getstate ");
++
++      if (!urb->buffer || urb->buffer_length < sizeof(u_int8_t)) {
++              debug("invalid urb! ");
++              return;
++      }
++
++      urb->buffer[0] = urb->device->dfu_state & 0xff;
++      urb->actual_length = sizeof(u_int8_t);
++}
++
++#ifndef CONFIG_USBD_PRODUCTID_DFU
++#define CONFIG_USBD_PRODUCTID_DFU CONFIG_USBD_PRODUCTID_CDCACM
++#endif
++
++static const struct usb_device_descriptor dfu_dev_descriptor = {
++      .bLength                = USB_DT_DEVICE_SIZE,
++      .bDescriptorType        = USB_DT_DEVICE,
++      .bcdUSB                 = 0x0100,
++      .bDeviceClass           = 0x00,
++      .bDeviceSubClass        = 0x00,
++      .bDeviceProtocol        = 0x00,
++      .bMaxPacketSize0        = EP0_MAX_PACKET_SIZE,
++      .idVendor               = CONFIG_USBD_VENDORID,
++      .idProduct              = CONFIG_USBD_PRODUCTID_DFU,
++      .bcdDevice              = 0x0000,
++      .iManufacturer          = DFU_STR_MANUFACTURER,
++      .iProduct               = DFU_STR_PRODUCT,
++      .iSerialNumber          = DFU_STR_SERIAL,
++      .bNumConfigurations     = 0x01,
++};
++
++static const struct _dfu_desc dfu_cfg_descriptor = {
++      .ucfg = {
++              .bLength                = USB_DT_CONFIG_SIZE,
++              .bDescriptorType        = USB_DT_CONFIG,
++              .wTotalLength           = USB_DT_CONFIG_SIZE +
++                                        DFU_NUM_ALTERNATES * USB_DT_INTERFACE_SIZE +
++                                        USB_DT_DFU_SIZE,
++              .bNumInterfaces         = 5,
++              .bConfigurationValue    = 1,
++              .iConfiguration         = DFU_STR_CONFIG,
++              .bmAttributes           = BMATTRIBUTE_RESERVED,
++              .bMaxPower              = 50,
++      },
++      .uif[0] = {
++              .bLength                = USB_DT_INTERFACE_SIZE,
++              .bDescriptorType        = USB_DT_INTERFACE,
++              .bInterfaceNumber       = 0x00,
++              .bAlternateSetting      = 0x00,
++              .bNumEndpoints          = 0x00,
++              .bInterfaceClass        = 0xfe,
++              .bInterfaceSubClass     = 0x01,
++              .bInterfaceProtocol     = 0x02,
++              .iInterface             = DFU_STR_ALT0,
++      },
++      .uif[1] = {
++              .bLength                = USB_DT_INTERFACE_SIZE,
++              .bDescriptorType        = USB_DT_INTERFACE,
++              .bInterfaceNumber       = 0x00,
++              .bAlternateSetting      = 0x01,
++              .bNumEndpoints          = 0x00,
++              .bInterfaceClass        = 0xfe,
++              .bInterfaceSubClass     = 0x01,
++              .bInterfaceProtocol     = 0x02,
++              .iInterface             = DFU_STR_ALT1,
++      },
++      .uif[2] = {
++              .bLength                = USB_DT_INTERFACE_SIZE,
++              .bDescriptorType        = USB_DT_INTERFACE,
++              .bInterfaceNumber       = 0x00,
++              .bAlternateSetting      = 0x02,
++              .bNumEndpoints          = 0x00,
++              .bInterfaceClass        = 0xfe,
++              .bInterfaceSubClass     = 0x01,
++              .bInterfaceProtocol     = 0x02,
++              .iInterface             = DFU_STR_ALT2,
++      },
++      .uif[3] = {
++              .bLength                = USB_DT_INTERFACE_SIZE,
++              .bDescriptorType        = USB_DT_INTERFACE,
++              .bInterfaceNumber       = 0x00,
++              .bAlternateSetting      = 0x03,
++              .bNumEndpoints          = 0x00,
++              .bInterfaceClass        = 0xfe,
++              .bInterfaceSubClass     = 0x01,
++              .bInterfaceProtocol     = 0x02,
++              .iInterface             = DFU_STR_ALT3,
++      },
++      .uif[4] = {
++              .bLength                = USB_DT_INTERFACE_SIZE,
++              .bDescriptorType        = USB_DT_INTERFACE,
++              .bInterfaceNumber       = 0x00,
++              .bAlternateSetting      = 0x04,
++              .bNumEndpoints          = 0x00,
++              .bInterfaceClass        = 0xfe,
++              .bInterfaceSubClass     = 0x01,
++              .bInterfaceProtocol     = 0x02,
++              .iInterface             = DFU_STR_ALT4,
++      },
++      .uif[5] = {
++              .bLength                = USB_DT_INTERFACE_SIZE,
++              .bDescriptorType        = USB_DT_INTERFACE,
++              .bInterfaceNumber       = 0x00,
++              .bAlternateSetting      = 0x05,
++              .bNumEndpoints          = 0x00,
++              .bInterfaceClass        = 0xfe,
++              .bInterfaceSubClass     = 0x01,
++              .bInterfaceProtocol     = 0x02,
++              .iInterface             = DFU_STR_ALT5,
++      },
++      .func_dfu = DFU_FUNC_DESC,
++};
++
++int dfu_ep0_handler(struct urb *urb)
++{
++      int rc, ret = RET_NOTHING;
++      u_int8_t req = urb->device_request.bRequest;
++      u_int16_t val = urb->device_request.wValue;
++      u_int16_t len = urb->device_request.wLength;
++      struct usb_device_instance *dev = urb->device;
++
++      debug("dfu_ep0(req=0x%x, val=0x%x, len=%u) old_state = %u ",
++              req, val, len, dev->dfu_state);
++
++      switch (dev->dfu_state) {
++      case DFU_STATE_appIDLE:
++              switch (req) {
++              case USB_REQ_DFU_GETSTATUS:
++                      handle_getstatus(urb, len);
++                      break;
++              case USB_REQ_DFU_GETSTATE:
++                      handle_getstate(urb, len);
++                      break;
++              case USB_REQ_DFU_DETACH:
++                      dev->dfu_state = DFU_STATE_appDETACH;
++                      ret = RET_ZLP;
++                      goto out;
++                      break;
++              default:
++                      ret = RET_STALL;
++              }
++              break;
++      case DFU_STATE_appDETACH:
++              switch (req) {
++              case USB_REQ_DFU_GETSTATUS:
++                      handle_getstatus(urb, len);
++                      break;
++              case USB_REQ_DFU_GETSTATE:
++                      handle_getstate(urb, len);
++                      break;
++              default:
++                      dev->dfu_state = DFU_STATE_appIDLE;
++                      ret = RET_STALL;
++                      goto out;
++                      break;
++              }
++              /* FIXME: implement timer to return to appIDLE */
++              break;
++      case DFU_STATE_dfuIDLE:
++              switch (req) {
++              case USB_REQ_DFU_DNLOAD:
++                      if (len == 0) {
++                              dev->dfu_state = DFU_STATE_dfuERROR;
++                              ret = RET_STALL;
++                              goto out;
++                      }
++                      dev->dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
++                      ret = handle_dnload(urb, val, len, 1);
++                      break;
++              case USB_REQ_DFU_UPLOAD:
++                      dev->dfu_state = DFU_STATE_dfuUPLOAD_IDLE;
++                      handle_upload(urb, val, len, 1);
++                      break;
++              case USB_REQ_DFU_ABORT:
++                      /* no zlp? */
++                      ret = RET_ZLP;
++                      break;
++              case USB_REQ_DFU_GETSTATUS:
++                      handle_getstatus(urb, len);
++                      break;
++              case USB_REQ_DFU_GETSTATE:
++                      handle_getstate(urb, len);
++                      break;
++              case USB_REQ_DFU_DETACH:
++                      /* Proprietary extension: 'detach' from idle mode and
++                       * get back to runtime mode in case of USB Reset.  As
++                       * much as I dislike this, we just can't use every USB
++                       * bus reset to switch back to runtime mode, since at
++                       * least the Linux USB stack likes to send a number of resets
++                       * in a row :( */
++                      dev->dfu_state = DFU_STATE_dfuMANIFEST_WAIT_RST;
++                      break;
++              default:
++                      dev->dfu_state = DFU_STATE_dfuERROR;
++                      ret = RET_STALL;
++                      goto out;
++                      break;
++              }
++              break;
++      case DFU_STATE_dfuDNLOAD_SYNC:
++              switch (req) {
++              case USB_REQ_DFU_GETSTATUS:
++                      handle_getstatus(urb, len);
++                      /* FIXME: state transition depending on block completeness */
++                      break;
++              case USB_REQ_DFU_GETSTATE:
++                      handle_getstate(urb, len);
++                      break;
++              default:
++                      dev->dfu_state = DFU_STATE_dfuERROR;
++                      ret = RET_STALL;
++                      goto out;
++              }
++              break;
++      case DFU_STATE_dfuDNBUSY:
++              switch (req) {
++              case USB_REQ_DFU_GETSTATUS:
++                      /* FIXME: only accept getstatus if bwPollTimeout
++                       * has elapsed */
++                      handle_getstatus(urb, len);
++                      break;
++              default:
++                      dev->dfu_state = DFU_STATE_dfuERROR;
++                      ret = RET_STALL;
++                      goto out;
++              }
++              break;
++      case DFU_STATE_dfuDNLOAD_IDLE:
++              switch (req) {
++              case USB_REQ_DFU_DNLOAD:
++                      dev->dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
++                      ret = handle_dnload(urb, val, len, 0);
++                      break;
++              case USB_REQ_DFU_ABORT:
++                      dev->dfu_state = DFU_STATE_dfuIDLE;
++                      ret = RET_ZLP;
++                      break;
++              case USB_REQ_DFU_GETSTATUS:
++                      handle_getstatus(urb, len);
++                      break;
++              case USB_REQ_DFU_GETSTATE:
++                      handle_getstate(urb, len);
++                      break;
++              default:
++                      dev->dfu_state = DFU_STATE_dfuERROR;
++                      ret = RET_STALL;
++                      break;
++              }
++              break;
++      case DFU_STATE_dfuMANIFEST_SYNC:
++              switch (req) {
++              case USB_REQ_DFU_GETSTATUS:
++                      /* We're MainfestationTolerant */
++                      dev->dfu_state = DFU_STATE_dfuIDLE;
++                      handle_getstatus(urb, len);
++                      break;
++              case USB_REQ_DFU_GETSTATE:
++                      handle_getstate(urb, len);
++                      break;
++              default:
++                      dev->dfu_state = DFU_STATE_dfuERROR;
++                      ret = RET_STALL;
++                      break;
++              }
++              break;
++      case DFU_STATE_dfuMANIFEST:
++              /* we should never go here */
++              dev->dfu_state = DFU_STATE_dfuERROR;
++              ret = RET_STALL;
++              break;
++      case DFU_STATE_dfuMANIFEST_WAIT_RST:
++              /* we should never go here */
++              break;
++      case DFU_STATE_dfuUPLOAD_IDLE:
++              switch (req) {
++              case USB_REQ_DFU_UPLOAD:
++                      /* state transition if less data then requested */
++                      rc = handle_upload(urb, val, len, 0);
++                      if (rc >= 0 && rc < len)
++                              dev->dfu_state = DFU_STATE_dfuIDLE;
++                      break;
++              case USB_REQ_DFU_ABORT:
++                      dev->dfu_state = DFU_STATE_dfuIDLE;
++                      /* no zlp? */
++                      ret = RET_ZLP;
++                      break;
++              case USB_REQ_DFU_GETSTATUS:
++                      handle_getstatus(urb, len);
++                      break;
++              case USB_REQ_DFU_GETSTATE:
++                      handle_getstate(urb, len);
++                      break;
++              default:
++                      dev->dfu_state = DFU_STATE_dfuERROR;
++                      ret = RET_STALL;
++                      break;
++              }
++              break;
++      case DFU_STATE_dfuERROR:
++              switch (req) {
++              case USB_REQ_DFU_GETSTATUS:
++                      handle_getstatus(urb, len);
++                      break;
++              case USB_REQ_DFU_GETSTATE:
++                      handle_getstate(urb, len);
++                      break;
++              case USB_REQ_DFU_CLRSTATUS:
++                      dev->dfu_state = DFU_STATE_dfuIDLE;
++                      dev->dfu_status = DFU_STATUS_OK;
++                      /* no zlp? */
++                      ret = RET_ZLP;
++                      break;
++              default:
++                      dev->dfu_state = DFU_STATE_dfuERROR;
++                      ret = RET_STALL;
++                      break;
++              }
++              break;
++      default:
++              return DFU_EP0_UNHANDLED;
++              break;
++      }
++
++out:
++      debug("new_state = %u, ret = %u\n", dev->dfu_state, ret);
++
++      switch (ret) {
++      case RET_ZLP:
++              //udc_ep0_send_zlp();
++              urb->actual_length = 0;
++              return DFU_EP0_ZLP;
++              break;
++      case RET_STALL:
++              //udc_ep0_send_stall();
++              return DFU_EP0_STALL;
++              break;
++      case RET_NOTHING:
++              break;
++      }
++
++      return DFU_EP0_DATA;
++}
++
++void str2wide (char *str, u16 * wide);
++static struct usb_string_descriptor *create_usbstring(char *string)
++{
++      struct usb_string_descriptor *strdesc;
++      int size = sizeof(*strdesc) + strlen(string)*2;
++
++      if (size > 255)
++              return NULL;
++
++      strdesc = malloc(size);
++      if (!strdesc)
++              return NULL;
++
++      strdesc->bLength = size;
++      strdesc->bDescriptorType = USB_DT_STRING;
++      str2wide(string, strdesc->wData);
++
++      return strdesc;
++}
++
++
++static void dfu_init_strings(struct usb_device_instance *dev)
++{
++      int i;
++      struct usb_string_descriptor *strdesc;
++
++      strdesc = create_usbstring(CONFIG_DFU_CFG_STR);
++      usb_strings[DFU_STR_CONFIG] = strdesc;
++
++      for (i = 0; i < DFU_NUM_ALTERNATES; i++) {
++              if (i == 0) {
++                      strdesc = create_usbstring(CONFIG_DFU_ALT0_STR);
++              } else {
++                      struct part_info *part = get_partition_nand(i-1);
++
++                      if (part)
++                              strdesc = create_usbstring(part->name);
++                      else
++                              strdesc =
++                                  create_usbstring("undefined partition");
++              }
++              if (!strdesc)
++                      continue;
++              usb_strings[STR_COUNT+i+1] = strdesc;
++      }
++}
++
++int dfu_init_instance(struct usb_device_instance *dev)
++{
++      dev->dfu_dev_desc = &dfu_dev_descriptor;
++      dev->dfu_cfg_desc = &dfu_cfg_descriptor;
++      dev->dfu_state = DFU_STATE_appIDLE;
++      dev->dfu_status = DFU_STATUS_OK;
++
++      if (system_dfu_state)
++              printf("SURPRISE: system_dfu_state is already set\n");
++      system_dfu_state = &dev->dfu_state;
++
++      dfu_init_strings(dev);
++
++      return 0;
++}
++
++static int stdout_switched;
++
++/* event handler for usb device state events */
++void dfu_event(struct usb_device_instance *device,
++             usb_device_event_t event, int data)
++{
++      char *out;
++
++      switch (event) {
++      case DEVICE_RESET:
++              switch (device->dfu_state) {
++              case DFU_STATE_appDETACH:
++                      device->dfu_state = DFU_STATE_dfuIDLE;
++                      out = getenv("stdout");
++                      if (out && !strcmp(out, "usbtty")) {
++                              setenv("stdout", "vga");
++                              setenv("stderr", "vga");
++                              stdout_switched = 1;
++                      }
++                      printf("DFU: Switching to DFU Mode\n");
++                      break;
++              case DFU_STATE_dfuMANIFEST_WAIT_RST:
++                      device->dfu_state = DFU_STATE_appIDLE;
++                      printf("DFU: Switching back to Runtime mode\n");
++                      if (stdout_switched) {
++                              setenv("stdout", "usbtty");
++                              setenv("stderr", "usbtty");
++                              stdout_switched = 0;
++                      }
++                      break;
++              default:
++                      break;
++              }
++              break;
++      case DEVICE_CONFIGURED:
++      case DEVICE_DE_CONFIGURED:
++              debug("SET_CONFIGURATION(%u) ", device->configuration);
++              /* fallthrough */
++      case DEVICE_SET_INTERFACE:
++              debug("SET_INTERFACE(%u,%u) old_state = %u ",
++                      device->interface, device->alternate,
++                      device->dfu_state);
++              switch (device->dfu_state) {
++              case DFU_STATE_appIDLE:
++              case DFU_STATE_appDETACH:
++              case DFU_STATE_dfuIDLE:
++              case DFU_STATE_dfuMANIFEST_WAIT_RST:
++                      /* do nothing, we're fine */
++                      break;
++              case DFU_STATE_dfuDNLOAD_SYNC:
++              case DFU_STATE_dfuDNBUSY:
++              case DFU_STATE_dfuDNLOAD_IDLE:
++              case DFU_STATE_dfuMANIFEST:
++                      device->dfu_state = DFU_STATE_dfuERROR;
++                      device->dfu_status = DFU_STATUS_errNOTDONE;
++                      /* FIXME: free malloc()ed buffer! */
++                      break;
++              case DFU_STATE_dfuMANIFEST_SYNC:
++              case DFU_STATE_dfuUPLOAD_IDLE:
++              case DFU_STATE_dfuERROR:
++                      device->dfu_state = DFU_STATE_dfuERROR;
++                      device->dfu_status = DFU_STATUS_errUNKNOWN;
++                      break;
++              }
++              debug("new_state = %u\n", device->dfu_state);
++              break;
++      default:
++              break;
++      }
++}
++#endif /* CONFIG_USBD_DFU */
+Index: u-boot/drivers/Makefile
+===================================================================
+--- u-boot.orig/drivers/Makefile
++++ u-boot/drivers/Makefile
+@@ -47,7 +47,7 @@
+         status_led.o sym53c8xx.o systemace.o ahci.o \
+         ti_pci1410a.o tigon3.o tsec.o \
+         tsi108_eth.o tsi108_i2c.o tsi108_pci.o \
+-        usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbdcore_s3c2410.o usbtty.o \
++        usbdcore.o usbdfu.o usbdcore_ep0.o usbdcore_omap1510.o usbdcore_s3c2410.o usbtty.o \
+         videomodes.o w83c553f.o \
+         ks8695eth.o \
+         pcf50606.o \
+Index: u-boot/drivers/usbdcore.c
+===================================================================
+--- u-boot.orig/drivers/usbdcore.c
++++ u-boot/drivers/usbdcore.c
+@@ -31,6 +31,7 @@
+ #include <malloc.h>
+ #include "usbdcore.h"
++#include <usb_dfu.h>
+ #define MAX_INTERFACES 2
+@@ -212,6 +213,10 @@
+  */
+ struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_instance *device, int port)
+ {
++#ifdef CONFIG_USBD_DFU
++      if (device->dfu_state != DFU_STATE_appIDLE)
++              return device->dfu_dev_desc;
++#endif
+       return (device->device_descriptor);
+ }
+@@ -232,6 +237,10 @@
+       if (!(configuration_instance = usbd_device_configuration_instance (device, port, configuration))) {
+               return NULL;
+       }
++#ifdef CONFIG_USBD_DFU
++      if (device->dfu_state != DFU_STATE_appIDLE)
++              return (&device->dfu_cfg_desc->ucfg);
++#endif
+       return (configuration_instance->configuration_descriptor);
+ }
+@@ -253,6 +262,13 @@
+       if (!(interface_instance = usbd_device_interface_instance (device, port, configuration, interface))) {
+               return NULL;
+       }
++#ifdef CONFIG_USBD_DFU
++      if (device->dfu_state != DFU_STATE_appIDLE) {
++              if (alternate < 0 || alternate >= DFU_NUM_ALTERNATES)
++                      return NULL;
++              return &device->dfu_cfg_desc->uif[alternate];
++      }
++#endif
+       if ((alternate < 0) || (alternate >= interface_instance->alternates)) {
+               return NULL;
+       }
+@@ -681,4 +697,7 @@
+               /* usbdbg("calling device->event"); */
+               device->event(device, event, data);
+       }
++#ifdef CONFIG_USBD_DFU
++      dfu_event(device, event, data);
++#endif
+ }
+Index: u-boot/drivers/usbtty.c
+===================================================================
+--- u-boot.orig/drivers/usbtty.c
++++ u-boot/drivers/usbtty.c
+@@ -31,6 +31,8 @@
+ #include "usbtty.h"
+ #include "usb_cdc_acm.h"
+ #include "usbdescriptors.h"
++#include <usb_dfu_descriptors.h>
++#include <usb_dfu.h>
+ #include <config.h>           /* If defined, override Linux identifiers with
+                                * vendor specific ones */
+@@ -118,7 +120,7 @@
+ static unsigned short rx_endpoint = 0;
+ static unsigned short tx_endpoint = 0;
+ static unsigned short interface_count = 0;
+-static struct usb_string_descriptor *usbtty_string_table[STR_COUNT];
++static struct usb_string_descriptor *usbtty_string_table[NUM_STRINGS];
+ /* USB Descriptor Strings */
+ static u8 wstrLang[4] = {4,USB_DT_STRING,0x9,0x4};
+@@ -169,6 +171,10 @@
+       struct usb_interface_descriptor data_class_interface;
+       struct usb_endpoint_descriptor 
+               data_endpoints[NUM_ENDPOINTS-1] __attribute__((packed));
++#ifdef CONFIG_USBD_DFU
++      struct usb_interface_descriptor uif_dfu;
++      struct usb_dfu_func_descriptor func_dfu;
++#endif
+ } __attribute__((packed));
+ static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = {
+@@ -179,7 +185,11 @@
+                       .bDescriptorType = USB_DT_CONFIG,
+                       .wTotalLength =  
+                               cpu_to_le16(sizeof(struct acm_config_desc)),
++#ifdef CONFIG_USBD_DFU
++                      .bNumInterfaces = NUM_ACM_INTERFACES +1,
++#else
+                       .bNumInterfaces = NUM_ACM_INTERFACES,
++#endif
+                       .bConfigurationValue = 1,
+                       .iConfiguration = STR_CONFIG,
+                       .bmAttributes = 
+@@ -278,6 +288,11 @@
+                               .bInterval              = 0xFF,
+                       },
+               },
++#ifdef CONFIG_USBD_DFU
++              /* Interface 3 */
++              .uif_dfu = DFU_RT_IF_DESC,
++              .func_dfu = DFU_FUNC_DESC,
++#endif
+       },
+ };    
+@@ -390,7 +405,7 @@
+ void usbtty_poll (void);
+ /* utility function for converting char* to wide string used by USB */
+-static void str2wide (char *str, u16 * wide)
++void str2wide (char *str, u16 * wide)
+ {
+       int i;
+       for (i = 0; i < strlen (str) && str[i]; i++){
+@@ -652,6 +667,9 @@
+       device_instance->bus = bus_instance;
+       device_instance->configurations = NUM_CONFIGS;
+       device_instance->configuration_instance_array = config_instance;
++#ifdef CONFIG_USBD_DFU
++      dfu_init_instance(device_instance);
++#endif
+       /* initialize bus instance */
+       memset (bus_instance, 0, sizeof (struct usb_bus_instance));
+Index: u-boot/include/configs/neo1973_gta01.h
+===================================================================
+--- u-boot.orig/include/configs/neo1973_gta01.h
++++ u-boot/include/configs/neo1973_gta01.h
+@@ -167,7 +167,7 @@
+  */
+ #define CONFIG_STACKSIZE      (128*1024)      /* regular stack */
+ #ifdef CONFIG_USE_IRQ
+-#define CONFIG_STACKSIZE_IRQ  (4*1024)        /* IRQ stack */
++#define CONFIG_STACKSIZE_IRQ  (8*1024)        /* IRQ stack */
+ #define CONFIG_STACKSIZE_FIQ  (4*1024)        /* FIQ stack */
+ #endif
+@@ -184,6 +184,10 @@
+ #define CONFIG_USBD_MANUFACTURER      "OpenMoko, Inc"
+ #define CONFIG_USBD_PRODUCT_NAME      "Neo1973 Bootloader " U_BOOT_VERSION
+ #define CONFIG_EXTRA_ENV_SETTINGS     "usbtty=cdc_acm\0"
++#define CONFIG_USBD_DFU                       1
++#define CONFIG_USBD_DFU_XFER_SIZE     4096    /* 0x4000 */
++#define CONFIG_USBD_DFU_INTERFACE     2
++
+ /*-----------------------------------------------------------------------
+  * Physical Memory Map
+Index: u-boot/include/usb_dfu.h
+===================================================================
+--- /dev/null
++++ u-boot/include/usb_dfu.h
+@@ -0,0 +1,99 @@
++#ifndef _DFU_H
++#define _DFU_H
++
++/* USB Device Firmware Update Implementation for u-boot
++ * (C) 2007 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * based on: USB Device Firmware Update Implementation for OpenPCD
++ * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
++ *
++ * This ought to be compliant to the USB DFU Spec 1.0 as available from
++ * http://www.usb.org/developers/devclass_docs/usbdfu10.pdf
++ *
++ *  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 <asm/types.h>
++#include <usbdescriptors.h>
++#include <usb_dfu_descriptors.h>
++#include <config.h>
++
++/* USB DFU functional descriptor */
++#define DFU_FUNC_DESC  {                                              \
++      .bLength                = USB_DT_DFU_SIZE,                      \
++      .bDescriptorType        = USB_DT_DFU,                           \
++      .bmAttributes           = USB_DFU_CAN_UPLOAD | USB_DFU_CAN_DOWNLOAD | USB_DFU_MANIFEST_TOL, \
++      .wDetachTimeOut         = 0xff00,                               \
++      .wTransferSize          = CONFIG_USBD_DFU_XFER_SIZE,            \
++      .bcdDFUVersion          = 0x0100,                               \
++}
++
++/* USB Interface descriptor in Runtime mode */
++#define DFU_RT_IF_DESC        {                                               \
++      .bLength                = USB_DT_INTERFACE_SIZE,                \
++      .bDescriptorType        = USB_DT_INTERFACE,                     \
++      .bInterfaceNumber       = CONFIG_USBD_DFU_INTERFACE,            \
++      .bAlternateSetting      = 0x00,                                 \
++      .bNumEndpoints          = 0x00,                                 \
++      .bInterfaceClass        = 0xfe,                                 \
++      .bInterfaceSubClass     = 0x01,                                 \
++      .bInterfaceProtocol     = 0x01,                                 \
++      .iInterface             = DFU_STR_CONFIG,                       \
++}
++
++#define ARRAY_SIZE(x)           (sizeof(x) / sizeof((x)[0]))
++
++#define DFU_NUM_ALTERNATES    6
++
++#define DFU_STR_MANUFACTURER  STR_MANUFACTURER
++#define DFU_STR_PRODUCT               STR_PRODUCT
++#define DFU_STR_SERIAL                STR_SERIAL
++#define DFU_STR_CONFIG                (STR_COUNT)
++#define DFU_STR_ALT0          (STR_COUNT+1)
++#define DFU_STR_ALT1          (STR_COUNT+2)
++#define DFU_STR_ALT2          (STR_COUNT+3)
++#define DFU_STR_ALT3          (STR_COUNT+4)
++#define DFU_STR_ALT4          (STR_COUNT+5)
++#define DFU_STR_ALT5          (STR_COUNT+6)
++#define DFU_STR_COUNT         (STR_COUNT+7)
++
++#define DFU_NUM_STRINGS               (STR_COUNT+8)
++
++#define CONFIG_DFU_CFG_STR    "USB Device Firmware Upgrade"
++#define CONFIG_DFU_ALT0_STR   "RAM 0x32000000"
++
++struct _dfu_desc {
++      struct usb_configuration_descriptor ucfg;
++      struct usb_interface_descriptor uif[DFU_NUM_ALTERNATES];
++      struct usb_dfu_func_descriptor func_dfu;
++};
++
++int dfu_init_instance(struct usb_device_instance *dev);
++
++#define DFU_EP0_NONE          0
++#define DFU_EP0_UNHANDLED     1
++#define DFU_EP0_STALL         2
++#define DFU_EP0_ZLP           3
++#define DFU_EP0_DATA          4
++
++extern volatile enum dfu_state *system_dfu_state; /* for 3rd parties */
++
++int dfu_ep0_handler(struct urb *urb);
++
++void dfu_event(struct usb_device_instance *device,
++             usb_device_event_t event, int data);
++
++#endif /* _DFU_H */
+Index: u-boot/include/usb_dfu_descriptors.h
+===================================================================
+--- /dev/null
++++ u-boot/include/usb_dfu_descriptors.h
+@@ -0,0 +1,94 @@
++#ifndef _USB_DFU_H
++#define _USB_DFU_H
++/* USB Device Firmware Update Implementation for OpenPCD
++ * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
++ *
++ * Protocol definitions for USB DFU
++ *
++ * This ought to be compliant to the USB DFU Spec 1.0 as available from
++ * http://www.usb.org/developers/devclass_docs/usbdfu10.pdf
++ *
++ *  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 <linux/types.h>
++
++#define USB_DT_DFU                    0x21
++
++struct usb_dfu_func_descriptor {
++      u_int8_t                bLength;
++      u_int8_t                bDescriptorType;
++      u_int8_t                bmAttributes;
++#define USB_DFU_CAN_DOWNLOAD  (1 << 0)
++#define USB_DFU_CAN_UPLOAD    (1 << 1)
++#define USB_DFU_MANIFEST_TOL  (1 << 2)
++#define USB_DFU_WILL_DETACH   (1 << 3)
++      u_int16_t               wDetachTimeOut;
++      u_int16_t               wTransferSize;
++      u_int16_t               bcdDFUVersion;
++} __attribute__ ((packed));
++
++#define USB_DT_DFU_SIZE                       9
++
++#define USB_TYPE_DFU          (USB_TYPE_CLASS|USB_RECIP_INTERFACE)
++
++/* DFU class-specific requests (Section 3, DFU Rev 1.1) */
++#define USB_REQ_DFU_DETACH    0x00
++#define USB_REQ_DFU_DNLOAD    0x01
++#define USB_REQ_DFU_UPLOAD    0x02
++#define USB_REQ_DFU_GETSTATUS 0x03
++#define USB_REQ_DFU_CLRSTATUS 0x04
++#define USB_REQ_DFU_GETSTATE  0x05
++#define USB_REQ_DFU_ABORT     0x06
++
++struct dfu_status {
++      u_int8_t bStatus;
++      u_int8_t bwPollTimeout[3];
++      u_int8_t bState;
++      u_int8_t iString;
++} __attribute__((packed));
++
++#define DFU_STATUS_OK                 0x00
++#define DFU_STATUS_errTARGET          0x01
++#define DFU_STATUS_errFILE            0x02
++#define DFU_STATUS_errWRITE           0x03
++#define DFU_STATUS_errERASE           0x04
++#define DFU_STATUS_errCHECK_ERASED    0x05
++#define DFU_STATUS_errPROG            0x06
++#define DFU_STATUS_errVERIFY          0x07
++#define DFU_STATUS_errADDRESS         0x08
++#define DFU_STATUS_errNOTDONE         0x09
++#define DFU_STATUS_errFIRMWARE                0x0a
++#define DFU_STATUS_errVENDOR          0x0b
++#define DFU_STATUS_errUSBR            0x0c
++#define DFU_STATUS_errPOR             0x0d
++#define DFU_STATUS_errUNKNOWN         0x0e
++#define DFU_STATUS_errSTALLEDPKT      0x0f
++
++enum dfu_state {
++      DFU_STATE_appIDLE               = 0,
++      DFU_STATE_appDETACH             = 1,
++      DFU_STATE_dfuIDLE               = 2,
++      DFU_STATE_dfuDNLOAD_SYNC        = 3,
++      DFU_STATE_dfuDNBUSY             = 4,
++      DFU_STATE_dfuDNLOAD_IDLE        = 5,
++      DFU_STATE_dfuMANIFEST_SYNC      = 6,
++      DFU_STATE_dfuMANIFEST           = 7,
++      DFU_STATE_dfuMANIFEST_WAIT_RST  = 8,
++      DFU_STATE_dfuUPLOAD_IDLE        = 9,
++      DFU_STATE_dfuERROR              = 10,
++};
++
++#endif /* _USB_DFU_H */
+Index: u-boot/include/usbdcore.h
+===================================================================
+--- u-boot.orig/include/usbdcore.h
++++ u-boot/include/usbdcore.h
+@@ -33,6 +33,7 @@
+ #include <common.h>
+ #include "usbdescriptors.h"
++#include <usb_dfu_descriptors.h>
+ #define MAX_URBS_QUEUED 5
+@@ -475,7 +476,11 @@
+  * function driver to inform it that data has arrived.
+  */
++#ifdef CONFIG_USBD_DFU
++#define URB_BUF_SIZE (128+CONFIG_USBD_DFU_XFER_SIZE)
++#else
+ #define URB_BUF_SIZE 128 /* in linux we'd malloc this, but in u-boot we prefer static data */
++#endif
+ struct urb {
+       struct usb_endpoint_instance *endpoint;
+@@ -603,6 +608,12 @@
+       unsigned long usbd_rxtx_timestamp;
+       unsigned long usbd_last_rxtx_timestamp;
++#ifdef CONFIG_USBD_DFU
++      const struct usb_device_descriptor *dfu_dev_desc;
++      const struct _dfu_desc *dfu_cfg_desc;
++      enum dfu_state dfu_state;
++      u_int8_t dfu_status;
++#endif
+ };
+ /* Bus Interface configuration structure
+@@ -632,6 +643,8 @@
+ extern char *usbd_device_requests[];
+ extern char *usbd_device_descriptors[];
++extern struct usb_string_descriptor **usb_strings;
++
+ void urb_link_init (urb_link * ul);
+ void urb_detach (struct urb *urb);
+ urb_link *first_urb_link (urb_link * hd);
+Index: u-boot/drivers/usbtty.h
+===================================================================
+--- u-boot.orig/drivers/usbtty.h
++++ u-boot/drivers/usbtty.h
+@@ -71,4 +71,10 @@
+ #define STR_CTRL_INTERFACE    0x06
+ #define STR_COUNT             0x07
++#ifdef CONFIG_USBD_DFU
++#define NUM_STRINGS           DFU_STR_COUNT
++#else
++#define NUM_STRINGS           STR_COUNT
++#endif
++
+ #endif
+Index: u-boot/include/configs/qt2410.h
+===================================================================
+--- u-boot.orig/include/configs/qt2410.h
++++ u-boot/include/configs/qt2410.h
+@@ -199,7 +199,8 @@
+ #define CONFIG_USBD_PRODUCT_NAME      "QT2410 Bootloader " U_BOOT_VERSION
+ #define CONFIG_EXTRA_ENV_SETTINGS     "usbtty=cdc_acm\0"
+ #define CONFIG_USBD_DFU                       1
+-#define CONFIG_USBD_DFU_XFER_SIZE     0x4000
++#define CONFIG_USBD_DFU_XFER_SIZE     4096
++#define CONFIG_USBD_DFU_INTERFACE     2
+ /*-----------------------------------------------------------------------
+  * Physical Memory Map
+Index: u-boot/tools/Makefile
+===================================================================
+--- u-boot.orig/tools/Makefile
++++ u-boot/tools/Makefile
+@@ -21,10 +21,10 @@
+ # MA 02111-1307 USA
+ #
+-BIN_FILES     = img2srec$(SFX) mkimage$(SFX) envcrc$(SFX) gen_eth_addr$(SFX) bmp_logo$(SFX)
++BIN_FILES     = img2srec$(SFX) mkimage$(SFX) envcrc$(SFX) gen_eth_addr$(SFX) bmp_logo$(SFX) mkudfu$(SFX)
+ OBJ_LINKS     = environment.o crc32.o
+-OBJ_FILES     = img2srec.o mkimage.o envcrc.o gen_eth_addr.o bmp_logo.o
++OBJ_FILES     = img2srec.o mkimage.o envcrc.o gen_eth_addr.o bmp_logo.o mkudfu.o
+ ifeq ($(ARCH),mips)
+ BIN_FILES     += inca-swap-bytes$(SFX)
+@@ -137,6 +137,10 @@
+               $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
+               $(STRIP) $@
++$(obj)mkudfu$(SFX):   $(obj)mkudfu.o
++              $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
++              $(STRIP) $@
++
+ $(obj)ncb$(SFX):      $(obj)ncb.o
+               $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
+               $(STRIP) $@
+Index: u-boot/tools/mkudfu.c
+===================================================================
+--- /dev/null
++++ u-boot/tools/mkudfu.c
+@@ -0,0 +1,314 @@
++/*
++ * USB DFU file trailer tool
++ * (C) Copyright by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * based on mkimage.c, copyright information as follows:
++ *
++ * (C) Copyright 2000-2004
++ * DENX Software Engineering
++ * Wolfgang Denk, wd@denx.de
++ * All rights reserved.
++ *
++ * 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 <errno.h>
++#include <fcntl.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#ifndef __WIN32__
++#include <netinet/in.h>               /* for host / network byte order conversions    */
++#endif
++#include <sys/mman.h>
++#include <sys/stat.h>
++#include <time.h>
++#include <unistd.h>
++
++#if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__)
++#include <inttypes.h>
++#endif
++
++#ifdef __WIN32__
++typedef unsigned int __u32;
++
++#define SWAP_LONG(x) \
++      ((__u32)( \
++              (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
++              (((__u32)(x) & (__u32)0x0000ff00UL) <<  8) | \
++              (((__u32)(x) & (__u32)0x00ff0000UL) >>  8) | \
++              (((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
++typedef               unsigned char   uint8_t;
++typedef               unsigned short  uint16_t;
++typedef               unsigned int    uint32_t;
++
++#define     ntohl(a)  SWAP_LONG(a)
++#define     htonl(a)  SWAP_LONG(a)
++#endif        /* __WIN32__ */
++
++#ifndef       O_BINARY                /* should be define'd on __WIN32__ */
++#define O_BINARY      0
++#endif
++
++#include <usb_dfu_trailer.h>
++
++extern int errno;
++
++#ifndef MAP_FAILED
++#define MAP_FAILED (-1)
++#endif
++
++static char *cmdname;
++
++static char *datafile;
++static char *imagefile;
++
++
++static void usage()
++{
++      fprintf (stderr, "%s - create / display u-boot DFU trailer\n", cmdname);
++      fprintf (stderr, "Usage: %s -l image\n"
++                       "          -l ==> list image header information\n"
++                       "       %s -v VID -p PID -r REV -d data_file image\n",
++              cmdname, cmdname);
++      fprintf (stderr, "          -v ==> set vendor ID to 'VID'\n"
++                       "          -p ==> set product ID system to 'PID'\n"
++                       "          -r ==> set hardware revision to 'REV'\n"
++                       "          -d ==> use 'data_file' as input file\n"
++              );
++      exit (EXIT_FAILURE);
++}
++
++static void print_trailer(struct uboot_dfu_trailer *trailer)
++{
++      printf("===> DFU Trailer information:\n");
++      printf("Trailer Vers.:  %d\n", trailer->version);
++      printf("Trailer Length: %d\n", trailer->length);
++      printf("VendorID:       0x%04x\n", trailer->vendor);
++      printf("ProductID:      0x%04x\n", trailer->product);
++      printf("HW Revision:    0x%04x\n", trailer->revision);
++}
++
++static void copy_file (int ifd, const char *datafile, int pad)
++{
++      int dfd;
++      struct stat sbuf;
++      unsigned char *ptr;
++      int tail;
++      int zero = 0;
++      int offset = 0;
++      int size;
++
++      if ((dfd = open(datafile, O_RDONLY|O_BINARY)) < 0) {
++              fprintf (stderr, "%s: Can't open %s: %s\n",
++                      cmdname, datafile, strerror(errno));
++              exit (EXIT_FAILURE);
++      }
++
++      if (fstat(dfd, &sbuf) < 0) {
++              fprintf (stderr, "%s: Can't stat %s: %s\n",
++                      cmdname, datafile, strerror(errno));
++              exit (EXIT_FAILURE);
++      }
++
++      ptr = (unsigned char *)mmap(0, sbuf.st_size,
++                                  PROT_READ, MAP_SHARED, dfd, 0);
++      if (ptr == (unsigned char *)MAP_FAILED) {
++              fprintf (stderr, "%s: Can't read %s: %s\n",
++                      cmdname, datafile, strerror(errno));
++              exit (EXIT_FAILURE);
++      }
++
++      size = sbuf.st_size - offset;
++      if (write(ifd, ptr + offset, size) != size) {
++              fprintf (stderr, "%s: Write error on %s: %s\n",
++                      cmdname, imagefile, strerror(errno));
++              exit (EXIT_FAILURE);
++      }
++
++      if (pad && ((tail = size % 4) != 0)) {
++
++              if (write(ifd, (char *)&zero, 4-tail) != 4-tail) {
++                      fprintf (stderr, "%s: Write error on %s: %s\n",
++                              cmdname, imagefile, strerror(errno));
++                      exit (EXIT_FAILURE);
++              }
++      }
++
++      (void) munmap((void *)ptr, sbuf.st_size);
++      (void) close (dfd);
++}
++
++
++int main(int argc, char **argv)
++{
++      int ifd;
++      int lflag = 0;
++      struct stat sbuf;
++      u_int16_t opt_vendor, opt_product, opt_revision;
++      struct uboot_dfu_trailer _hdr, _mirror, *hdr = &_hdr;
++
++      opt_vendor = opt_product = opt_revision = 0;
++
++      cmdname = *argv;
++
++      while (--argc > 0 && **++argv == '-') {
++              while (*++*argv) {
++                      switch (**argv) {
++                      case 'l':
++                              lflag = 1;
++                              break;
++                      case 'v':
++                              if (--argc <= 0)
++                                      usage ();
++                              opt_vendor = strtoul(*++argv, NULL, 16);
++                              goto NXTARG;
++                      case 'p':
++                              if (--argc <= 0)
++                                      usage ();
++                              opt_product = strtoul(*++argv, NULL, 16);
++                              goto NXTARG;
++                      case 'r':
++                              if (--argc <= 0)
++                                      usage ();
++                              opt_revision = strtoul(*++argv, NULL, 16);
++                              goto NXTARG;
++                      case 'd':
++                              if (--argc <= 0)
++                                      usage ();
++                              datafile = *++argv;
++                              goto NXTARG;
++                      case 'h':
++                              usage();
++                              break;
++                      default:
++                              usage();
++                      }
++              }
++NXTARG:               ;
++      }
++
++      if (argc != 1)
++              usage();
++
++      imagefile = *argv;
++
++      if (lflag)
++              ifd = open(imagefile, O_RDONLY|O_BINARY);
++      else
++              ifd = open(imagefile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666);
++
++      if (ifd < 0) {
++              fprintf (stderr, "%s: Can't open %s: %s\n",
++                      cmdname, imagefile, strerror(errno));
++              exit (EXIT_FAILURE);
++      }
++
++      if (lflag) {
++              unsigned char *ptr;
++              /* list header information of existing image */
++              if (fstat(ifd, &sbuf) < 0) {
++                      fprintf (stderr, "%s: Can't stat %s: %s\n",
++                              cmdname, imagefile, strerror(errno));
++                      exit (EXIT_FAILURE);
++              }
++
++              if ((unsigned)sbuf.st_size < sizeof(struct uboot_dfu_trailer)) {
++                      fprintf (stderr,
++                              "%s: Bad size: \"%s\" is no valid image\n",
++                              cmdname, imagefile);
++                      exit (EXIT_FAILURE);
++              }
++
++              ptr = (unsigned char *)mmap(0, sbuf.st_size,
++                                          PROT_READ, MAP_SHARED, ifd, 0);
++              if ((caddr_t)ptr == (caddr_t)-1) {
++                      fprintf (stderr, "%s: Can't read %s: %s\n",
++                              cmdname, imagefile, strerror(errno));
++                      exit (EXIT_FAILURE);
++              }
++
++              dfu_trailer_mirror(hdr, ptr+sbuf.st_size);
++
++              if (hdr->magic != UBOOT_DFU_TRAILER_MAGIC) {
++                      fprintf (stderr,
++                              "%s: Bad Magic Number: \"%s\" is no valid image\n",
++                              cmdname, imagefile);
++                      exit (EXIT_FAILURE);
++              }
++
++              /* for multi-file images we need the data part, too */
++              print_trailer(hdr);
++
++              (void) munmap((void *)ptr, sbuf.st_size);
++              (void) close (ifd);
++
++              exit (EXIT_SUCCESS);
++      }
++
++      /* if we're not listing: */
++
++      copy_file (ifd, datafile, 0);
++
++      memset (hdr, 0, sizeof(struct uboot_dfu_trailer));
++
++      /* Build new header */
++      hdr->version    = UBOOT_DFU_TRAILER_V1;
++      hdr->magic      = UBOOT_DFU_TRAILER_MAGIC;
++      hdr->length     = sizeof(struct uboot_dfu_trailer);
++      hdr->vendor     = opt_vendor;
++      hdr->product    = opt_product;
++      hdr->revision   = opt_revision;
++
++      print_trailer(hdr);
++      dfu_trailer_mirror(&_mirror, (unsigned char *)hdr+sizeof(*hdr));
++
++      if (write(ifd, &_mirror, sizeof(struct uboot_dfu_trailer))
++                                      != sizeof(struct uboot_dfu_trailer)) {
++              fprintf (stderr, "%s: Write error on %s: %s\n",
++                      cmdname, imagefile, strerror(errno));
++              exit (EXIT_FAILURE);
++      }
++
++      /* We're a bit of paranoid */
++#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__)
++      (void) fdatasync (ifd);
++#else
++      (void) fsync (ifd);
++#endif
++
++      if (fstat(ifd, &sbuf) < 0) {
++              fprintf (stderr, "%s: Can't stat %s: %s\n",
++                      cmdname, imagefile, strerror(errno));
++              exit (EXIT_FAILURE);
++      }
++
++      /* We're a bit of paranoid */
++#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__)
++      (void) fdatasync (ifd);
++#else
++      (void) fsync (ifd);
++#endif
++
++      if (close(ifd)) {
++              fprintf (stderr, "%s: Write error on %s: %s\n",
++                      cmdname, imagefile, strerror(errno));
++              exit (EXIT_FAILURE);
++      }
++
++      exit (EXIT_SUCCESS);
++}
+Index: u-boot/include/usb_dfu_trailer.h
+===================================================================
+--- /dev/null
++++ u-boot/include/usb_dfu_trailer.h
+@@ -0,0 +1,31 @@
++#ifndef _USB_DFU_TRAILER_H
++#define _USB_DFU_TRAILER_H
++
++/* trailer handling for DFU files */
++
++#define UBOOT_DFU_TRAILER_V1  1
++#define UBOOT_DFU_TRAILER_MAGIC       0x19731978
++struct uboot_dfu_trailer {
++      u_int32_t       magic;
++      u_int16_t       version;
++      u_int16_t       length;
++      u_int16_t       vendor;
++      u_int16_t       product;
++      u_int32_t       revision;
++} __attribute__((packed));
++
++/* we mirror the trailer because we want it to be longer in later versions
++ * while keeping backwards compatibility */
++static inline void dfu_trailer_mirror(struct uboot_dfu_trailer *trailer,
++                                    unsigned char *eof)
++{
++      int i;
++      int len = sizeof(struct uboot_dfu_trailer);
++      unsigned char *src = eof - len;
++      unsigned char *dst = (unsigned char *) trailer;
++
++      for (i = 0; i < len; i++)
++              dst[len-1-i] = src[i];
++}
++
++#endif /* _USB_DFU_TRAILER_H */
+Index: u-boot/Makefile
+===================================================================
+--- u-boot.orig/Makefile
++++ u-boot/Makefile
+@@ -261,6 +261,12 @@
+ $(obj)u-boot.bin:     $(obj)u-boot
+               $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
++$(obj)u-boot.udfu:    $(obj)u-boot.bin
++              ./tools/mkudfu -v $(CONFIG_USB_DFU_VENDOR) \
++                             -p $(CONFIG_USB_DFU_PRODUCT) \
++                             -r $(CONFIG_USB_DFU_REVISION) \
++                             -d $< $@
++
+ $(obj)u-boot.img:     $(obj)u-boot.bin
+               ./tools/mkimage -A $(ARCH) -T firmware -C none \
+               -a $(TEXT_BASE) -e 0 \
+Index: u-boot/board/neo1973/gta01/split_by_variant.sh
+===================================================================
+--- u-boot.orig/board/neo1973/gta01/split_by_variant.sh
++++ u-boot/board/neo1973/gta01/split_by_variant.sh
+@@ -15,37 +15,44 @@
+       echo "$0:: No parameters - using GTA01Bv3 config"
+       echo "#define CONFIG_ARCH_GTA01B_v3" > $CFGINC
+       echo "GTA01_BIG_RAM=y" > $CFGTMP
++      echo "CONFIG_USB_DFU_REVISION=0x0230" > $CFGTMP
+ else
+       case "$1" in
+       gta01v4_config)
+       echo "#define CONFIG_ARCH_GTA01_v4" > $CFGINC
+       echo "GTA01_BIG_RAM=n" > $CFGTMP
++      echo "CONFIG_USB_DFU_REVISION=0x0140" > $CFGTMP
+       ;;
+       gta01v3_config)
+       echo "#define CONFIG_ARCH_GTA01_v3" > $CFGINC
+       echo "GTA01_BIG_RAM=n" > $CFGTMP
++      echo "CONFIG_USB_DFU_REVISION=0x0130" > $CFGTMP
+       ;;
+       gta01bv2_config)
+       echo "#define CONFIG_ARCH_GTA01B_v2" > $CFGINC
+       echo "GTA01_BIG_RAM=y" > $CFGTMP
++      echo "CONFIG_USB_DFU_REVISION=0x0220" > $CFGTMP
+       ;;
+       gta01bv3_config)
+       echo "#define CONFIG_ARCH_GTA01B_v3" > $CFGINC
+       echo "GTA01_BIG_RAM=y" > $CFGTMP
++      echo "CONFIG_USB_DFU_REVISION=0x0230" > $CFGTMP
+       ;;
+       gta01bv4_config)
+       echo "#define CONFIG_ARCH_GTA01B_v4" > $CFGINC
+       echo "GTA01_BIG_RAM=y" > $CFGTMP
++      echo "CONFIG_USB_DFU_REVISION=0x0240" > $CFGTMP
+       ;;
+       *)
+       echo "$0:: Unrecognised config - using GTA01Bv4 config"
+       echo "#define CONFIG_ARCH_GTA01B_v4" > $CFGINC
+       echo "GTA01_BIG_RAM=y" > $CFGTMP
++      echo "CONFIG_USB_DFU_REVISION=0x0240" > $CFGTMP
+       ;;
+       esac
+Index: u-boot/board/neo1973/gta01/config.mk
+===================================================================
+--- u-boot.orig/board/neo1973/gta01/config.mk
++++ u-boot/board/neo1973/gta01/config.mk
+@@ -24,6 +24,9 @@
+ #
+ # download area is 3200'0000 or 3300'0000
++CONFIG_USB_DFU_VENDOR=0x1457
++CONFIG_USB_DFU_PRODUCT=0x5119
++
+ sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
+ ifeq ($(GTA01_BIG_RAM),y)
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-gta02.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-gta02.patch
new file mode 100644 (file)
index 0000000..ca54ebe
--- /dev/null
@@ -0,0 +1,1560 @@
+Add support for new GTA02 version of Neo1973
+
+Index: u-boot/Makefile
+===================================================================
+--- u-boot.orig/Makefile
++++ u-boot/Makefile
+@@ -2038,6 +2038,10 @@
+ sbc2410x_config: unconfig
+       @$(MKCONFIG) $(@:_config=) arm arm920t sbc2410x NULL s3c24x0
++gta02_config \
++gta02v1_config :      unconfig
++      @sh board/neo1973/gta02/split_by_variant.sh $@
++
+ gta01_config \
+ gta01v3_config \
+ gta01bv2_config \
+Index: u-boot/board/neo1973/gta02/Makefile
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/gta02/Makefile
+@@ -0,0 +1,64 @@
++#
++# (C) Copyright 2000, 2001, 2002
++# Wolfgang Denk, DENX Software Engineering, wd@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
++#
++
++include $(TOPDIR)/config.mk
++
++LIB   = lib$(BOARD).a
++
++OBJS  := gta02.o pcf50633.o ../common/cmd_neo1973.o ../common/jbt6k74.o ../common/udc.o ../common/bootmenu.o
++SOBJS := ../common/lowlevel_init.o
++
++.PHONY:       all
++
++all:  $(LIB) lowevel_foo.bin
++
++$(LIB):       $(OBJS) $(SOBJS)
++      $(AR) crv $@ $(OBJS) $(SOBJS)
++
++lowlevel_foo.o:       ../common/lowlevel_foo.S
++      $(CC) -c -DTEXT_BASE=0x33F80000 -march=armv4 \
++        -o lowlevel_foo.o ../common/lowlevel_foo.S
++
++lowlevel_foo: lowlevel_foo.o ../common/lowlevel_init.o ../common/lowlevel_foo.lds
++      $(LD) -T ../common/lowlevel_foo.lds -Ttext 0x33f80000 -Bstatic \
++        ../common/lowlevel_init.o lowlevel_foo.o -o lowlevel_foo
++
++lowevel_foo.bin:      lowlevel_foo
++      $(CROSS_COMPILE)objcopy --gap-fill=0xff -O binary \
++        lowlevel_foo lowlevel_foo.bin
++
++
++clean:
++      rm -f $(SOBJS) $(OBJS) lowlevel_foo lowlevel_foo.o
++
++distclean:    clean
++      rm -f $(LIB) core *.bak .depend lowlevel_foo.bin
++
++#########################################################################
++
++.depend:      Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
++              $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
++
++-include .depend
++
++#########################################################################
+Index: u-boot/board/neo1973/gta02/gta02.c
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/gta02/gta02.c
+@@ -0,0 +1,313 @@
++/*
++ * (C) 2006-2007 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * based on existing S3C2410 startup code in u-boot:
++ *
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Marius Groeger <mgroeger@sysgo.de>
++ *
++ * (C) Copyright 2002
++ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++ *
++ * 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 <s3c2440.h>
++#include <i2c.h>
++
++#include "../common/neo1973.h"
++#include "../common/jbt6k74.h"
++
++#include "pcf50633.h"
++
++DECLARE_GLOBAL_DATA_PTR;
++
++/* That many seconds the power key needs to be pressed to power up */
++#define POWER_KEY_SECONDS     2
++
++#define M_MDIV        0x7f            /* Fout = 405.00MHz */
++#define M_PDIV        0x2
++#define M_SDIV        0x1
++
++#define U_M_MDIV      0x38
++#define U_M_PDIV      0x2
++#define U_M_SDIV      0x2
++
++unsigned int neo1973_wakeup_cause;
++extern int nobootdelay;
++
++static inline void delay (unsigned long loops)
++{
++      __asm__ volatile ("1:\n"
++        "subs %0, %1, #1\n"
++        "bne 1b":"=r" (loops):"0" (loops));
++}
++
++/*
++ * Miscellaneous platform dependent initialisations
++ */
++
++int board_init (void)
++{
++      S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++      /* to reduce PLL lock time, adjust the LOCKTIME register */
++      clk_power->LOCKTIME = 0xFFFFFF;
++
++      /* configure MPLL */
++      clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
++
++      /* some delay between MPLL and UPLL */
++      delay (4000);
++
++      /* configure UPLL */
++      clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
++
++      /* some delay between MPLL and UPLL */
++      delay (8000);
++
++      /* set up the I/O ports */
++#if defined(CONFIG_ARCH_GTA02_v1)
++      gpio->GPACON = 0x007E1FFF;
++      gpio->GPADAT |= (1 << 16);      /* Set GPA16 to high (nNAND_WP) */
++
++      gpio->GPBCON = 0x00155555;
++      gpio->GPBUP = 0x000007FF;
++
++      gpio->GPCCON = 0x55551155;
++      gpio->GPCUP = 0x0000FFFF;
++
++      gpio->GPDCON = 0x55555555;
++      gpio->GPDUP = 0x0000FFFF;
++
++      gpio->GPECON = 0xAAAAAAAA;
++      gpio->GPEUP = 0x0000FFFF;
++
++      gpio->GPFCON = 0x0000AAAA;
++      gpio->GPFUP = 0x000000FF;
++
++      gpio->GPGCON = 0x013DFDFA;
++      gpio->GPGUP = 0x0000FFFF;
++
++      gpio->GPHCON = 0x0028AAAA;
++      gpio->GPHUP = 0x000007FF;
++
++      gpio->GPJCON = 0x1545541;
++#else
++#error Please define GTA02 version
++#endif
++
++      /* arch number of SMDK2410-Board */
++      gd->bd->bi_arch_number = MACH_TYPE_NEO1973_GTA02;
++
++      /* adress of boot parameters */
++      gd->bd->bi_boot_params = 0x30000100;
++
++      icache_enable();
++      dcache_enable();
++
++      return 0;
++}
++
++int board_late_init(void)
++{
++      extern unsigned char booted_from_nand;
++      unsigned char tmp;
++      char buf[32];
++      int menu_vote = 0; /* <= 0: no, > 0: yes */
++      int seconds = 0;
++
++      /* Initialize the Power Management Unit with a safe register set */
++      pcf50633_init();
++#if 0
++      /* if there's no other reason, must be regular reset */
++      neo1973_wakeup_cause = NEO1973_WAKEUP_RESET;
++
++      if (!booted_from_nand)
++              goto woken_by_reset;
++
++      /* obtain wake-up reason, save INT1 in environment */
++      tmp = pcf50606_reg_read(PCF50606_REG_INT1);
++      sprintf(buf, "0x%02x", tmp);
++      setenv("pcf50606_int1", buf);
++
++      if (tmp & PCF50606_INT1_ALARM) {
++              /* we've been woken up by RTC alarm, boot */
++              neo1973_wakeup_cause = NEO1973_WAKEUP_ALARM;
++              goto continue_boot;
++      }
++      if (tmp & PCF50606_INT1_EXTONR) {
++              /* we've been woken up by charger insert */
++              neo1973_wakeup_cause = NEO1973_WAKEUP_CHARGER;
++      }
++
++      if (tmp & PCF50606_INT1_ONKEYF) {
++              /* we've been woken up by a falling edge of the onkey */
++              neo1973_wakeup_cause = NEO1973_WAKEUP_POWER_KEY;
++      }
++
++      if (neo1973_wakeup_cause == NEO1973_WAKEUP_CHARGER) {
++              /* if we still think it was only a charger insert, boot */
++              goto continue_boot;
++      }
++
++woken_by_reset:
++
++      while (neo1973_wakeup_cause == NEO1973_WAKEUP_RESET ||
++          neo1973_on_key_pressed()) {
++              if (neo1973_aux_key_pressed())
++                      menu_vote++;
++              else
++                      menu_vote--;
++
++              if (neo1973_new_second())
++                      seconds++;
++              if (seconds >= POWER_KEY_SECONDS)
++                      goto continue_boot;
++      }
++      /* Power off if minimum number of seconds not reached */
++      neo1973_poweroff();
++
++continue_boot:
++      jbt6k74_init();
++      jbt6k74_enter_state(JBT_STATE_NORMAL);
++      jbt6k74_display_onoff(1);
++#endif
++
++      /* issue a short pulse with the vibrator */
++      neo1973_vibrator(1);
++      udelay(50000);
++      neo1973_vibrator(0);
++
++      /* switch on the backlight */
++      neo1973_backlight(1);
++
++#if 0
++      {
++              /* check if sd card is inserted, and power-up if it is */
++              S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++              if (!(gpio->GPFDAT & (1 << 5)))
++                      gpio->GPBDAT &= ~(1 << 2);
++      }
++
++      if (menu_vote > 0) {
++              bootmenu();
++              nobootdelay = 1;
++      }
++#endif
++
++      return 0;
++}
++
++int dram_init (void)
++{
++      gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
++      gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
++
++      return 0;
++}
++
++u_int32_t get_board_rev(void)
++{
++#if defined(CONFIG_ARCH_GTA02_v1)
++      return 0x00000310;
++#endif
++}
++
++void neo1973_poweroff(void)
++{
++      printf("poweroff\n");
++      udc_disconnect();
++      pcf50633_reg_write(PCF50633_REG_OOCSHDWN, 0x01);
++      /* don't return to caller */
++      while (1) ;
++}
++
++void neo1973_backlight(int on)
++{
++      /* FIXME: PMU based implementation */
++}
++
++/* FIXME: shared */
++void neo1973_vibrator(int on)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++      if (on)
++#if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
++              gpio->GPGDAT |= (1 << 11);      /* GPG11 */
++#elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
++              gpio->GPBDAT |= (1 << 10);      /* GPB10 */
++#elif defined(CONFIG_ARCH_GTA01B_v4) || defined(CONFIG_ARCH_GTA02_v1)
++              gpio->GPBDAT |= (1 << 3);       /* GPB3 */
++#endif
++      else
++#if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
++              gpio->GPGDAT &= ~(1 << 11);     /* GPG11 */
++#elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
++              gpio->GPBDAT &= ~(1 << 10);     /* GPB10 */
++#elif defined(CONFIG_ARCH_GTA01B_v4) || defined(CONFIG_ARCH_GTA02_v1)
++              gpio->GPBDAT &= ~(1 << 3);      /* GPB3 */
++#endif
++}
++
++int neo1973_new_second(void)
++{
++      return pcf50633_reg_read(PCF50633_REG_INT1) & PCF50633_INT1_SECOND;
++}
++
++int neo1973_on_key_pressed(void)
++{
++      return !(pcf50633_reg_read(PCF50633_REG_OOCSTAT)
++                                              & PCF50633_OOCSTAT_ONKEY);
++}
++
++/* FIXME: shared */
++int neo1973_aux_key_pressed(void)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++      if (gpio->GPFDAT & (1 << 6))
++              return 0;
++      return 1;
++}
++
++/* The sum of all part_size[]s must equal to the NAND size, i.e., 0x4000000.
++   "initrd" is sized such that it can hold two uncompressed 16 bit 640*480
++   images: 640*480*2*2 = 1228800 < 1245184. */
++
++unsigned int dynpart_size[] = {
++    CFG_UBOOT_SIZE, CFG_ENV_SIZE, 0x200000, 0xa0000, 0x1fce0000, 0 };
++char *dynpart_names[] = {
++    "u-boot", "u-boot_env", "kernel", "splash", "rootfs", NULL };
++
++
++const char *neo1973_get_charge_status(void)
++{
++      /* FIXME */
++      return "unknown";
++}
++
++int neo1973_set_charge_mode(enum neo1973_charger_cmd cmd)
++{
++      /* FIXME */
++      return 0;
++}
+Index: u-boot/board/neo1973/gta02/u-boot.lds
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/gta02/u-boot.lds
+@@ -0,0 +1,58 @@
++/*
++ * (C) Copyright 2002
++ * Gary Jennejohn, DENX Software Engineering, <gj@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_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
++OUTPUT_ARCH(arm)
++ENTRY(_start)
++SECTIONS
++{
++      . = 0x00000000;
++
++      . = ALIGN(4);
++      .text      :
++      {
++        cpu/arm920t/start.o   (.text)
++        cpu/arm920t/s3c24x0/nand_read.o (.text)
++        *(.text)
++      }
++
++      . = ALIGN(4);
++      .rodata : { *(.rodata) }
++
++      . = ALIGN(4);
++      .data : { *(.data) }
++
++      . = ALIGN(4);
++      .got : { *(.got) }
++
++      . = .;
++      __u_boot_cmd_start = .;
++      .u_boot_cmd : { *(.u_boot_cmd) }
++      __u_boot_cmd_end = .;
++
++      . = ALIGN(4);
++      __bss_start = .;
++      .bss : { *(.bss) }
++      _end = .;
++}
+Index: u-boot/include/configs/neo1973_gta02.h
+===================================================================
+--- /dev/null
++++ u-boot/include/configs/neo1973_gta02.h
+@@ -0,0 +1,276 @@
++/*
++ * (C) Copyright 2007 OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * Configuation settings for the FIC Neo1973 GTA02 Linux GSM phone
++ *
++ * 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
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/* we want to be able to start u-boot directly from within NAND flash */
++#define CONFIG_LL_INIT_NAND_ONLY
++#define CONFIG_S3C2410_NAND_BOOT      1
++#define CONFIG_S3C2410_NAND_SKIP_BAD  1
++
++#define CFG_UBOOT_SIZE                0x40000 /* size of u-boot, for NAND loading */
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++#define CONFIG_ARM920T                1       /* This is an ARM920T Core      */
++#define       CONFIG_S3C2440          1       /* in a SAMSUNG S3C2410 SoC     */
++#define CONFIG_SMDK2440               1       /* on a SAMSUNG SMDK2410 Board  */
++
++/* input clock of PLL */
++#define CONFIG_SYS_CLK_FREQ   12000000/* the GTA02 has this input clock */
++
++
++#define USE_920T_MMU          1
++#define CONFIG_USE_IRQ                1
++
++/*
++ * Size of malloc() pool
++ */
++#define CFG_MALLOC_LEN                (CFG_ENV_SIZE + 400*1024)
++                                      /* >> CFG_VIDEO_LOGO_MAX_SIZE */
++#define CFG_GBL_DATA_SIZE     128     /* size in bytes reserved for initial data */
++
++/*
++ * Hardware drivers
++ */
++
++/*
++ * select serial console configuration
++ */
++#define CONFIG_SERIAL3          1     /* we use SERIAL 1 on GTA01 */
++
++/************************************************************
++ * RTC
++ ************************************************************/
++#define       CONFIG_RTC_S3C24X0      1
++
++/* allow to overwrite serial and ethaddr */
++#define CONFIG_ENV_OVERWRITE
++
++#define CONFIG_BAUDRATE               115200
++
++/***********************************************************
++ * Command definition
++ ***********************************************************/
++#define CONFIG_COMMANDS (\
++                      CFG_CMD_BDI      | \
++                      CFG_CMD_LOADS    | \
++                      CFG_CMD_LAODB    | \
++                      CFG_CMD_IMI      | \
++                      CFG_CMD_CACHE    | \
++                      CFG_CMD_MEMORY   | \
++                      CFG_CMD_ENV      | \
++                      /* CFG_CMD_IRQ   | */  \
++                      CFG_CMD_BOOTD    | \
++                      CFG_CMD_CONSOLE  | \
++                      /* CFG_CMD_BMP   | */ \
++                      CFG_CMD_ASKENV   | \
++                      CFG_CMD_RUN      | \
++                      CFG_CMD_ECHO     | \
++                      CFG_CMD_I2C      | \
++                      CFG_CMD_REGINFO  | \
++                      CFG_CMD_IMMAP    | \
++                      CFG_CMD_DATE     | \
++                      CFG_CMD_AUTOSCRIPT | \
++                      CFG_CMD_BSP      | \
++                      CFG_CMD_ELF      | \
++                      CFG_CMD_MISC     | \
++                      /* CFG_CMD_USB   | */ \
++                      CFG_CMD_JFFS2    | \
++                      CFG_CMD_DIAG     | \
++                      /* CFG_CMD_HWFLOW        | */ \
++                      CFG_CMD_SAVES    | \
++                      CFG_CMD_NAND     | \
++                      CFG_CMD_PORTIO   | \
++                      CFG_CMD_MMC      | \
++                      CFG_CMD_FAT      | \
++                      CFG_CMD_EXT2     | \
++                      0)
++/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
++#include <cmd_confdefs.h>
++
++#define CONFIG_BOOTDELAY      3
++#define CONFIG_BOOTARGS       ""
++#define CONFIG_BOOTCOMMAND    "setenv bootargs ${bootargs_base} ${mtdparts}; nand read.e 0x32000000 kernel; bootm 0x32000000"
++
++#define CONFIG_DOS_PARTITION  1
++
++#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
++#define CONFIG_KGDB_BAUDRATE  115200          /* speed to run kgdb serial port */
++/* what's this ? it's not used anywhere */
++#define CONFIG_KGDB_SER_INDEX 1               /* which serial port to use */
++#endif
++
++/*
++ * Miscellaneous configurable options
++ */
++#define       CFG_LONGHELP                            /* undef to save memory         */
++#if defined(CONFIG_ARCH_GTA02_v1)
++#define       CFG_PROMPT              "GTA02v1 # "    /* Monitor Command Prompt       */
++#endif
++#define       CFG_CBSIZE              256             /* Console I/O Buffer Size      */
++#define       CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
++#define       CFG_MAXARGS             64              /* max number of command args   */
++#define CFG_BARGSIZE          CFG_CBSIZE      /* Boot Argument Buffer Size    */
++
++#define CFG_MEMTEST_START     0x30000000      /* memtest works on     */
++#define CFG_MEMTEST_END               0x33F00000      /* 63 MB in DRAM        */
++
++#undef  CFG_CLKS_IN_HZ                /* everything, incl board info, in Hz */
++
++#define       CFG_LOAD_ADDR           0x33000000      /* default load address */
++
++/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
++/* it to wrap 100 times (total 1562500) to get 1 sec. */
++#define       CFG_HZ                  1562500
++
++/* valid baudrates */
++#define CFG_BAUDRATE_TABLE    { 9600, 19200, 38400, 57600, 115200 }
++
++#define CFG_BOOTMENU
++
++/*-----------------------------------------------------------------------
++ * Stack sizes
++ *
++ * The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE      (128*1024)      /* regular stack */
++#ifdef CONFIG_USE_IRQ
++#define CONFIG_STACKSIZE_IRQ  (8*1024)        /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ  (4*1024)        /* FIQ stack */
++#endif
++
++#if 0
++#define CONFIG_USB_OHCI               1
++#endif
++
++#define CONFIG_USB_DEVICE     1
++#define CONFIG_USB_TTY                1
++#define CFG_CONSOLE_IS_IN_ENV 1
++#define CONFIG_USBD_VENDORID          0x1457     /* Linux/NetChip */
++#define CONFIG_USBD_PRODUCTID_GSERIAL 0x5120    /* gserial */
++#define CONFIG_USBD_PRODUCTID_CDCACM  0x5119    /* CDC ACM */
++#define CONFIG_USBD_MANUFACTURER      "OpenMoko, Inc"
++#define CONFIG_USBD_PRODUCT_NAME      "Neo1973 Bootloader " U_BOOT_VERSION
++#define CONFIG_USBD_DFU                       1
++#define CONFIG_USBD_DFU_XFER_SIZE     4096    /* 0x4000 */
++#define CONFIG_USBD_DFU_INTERFACE     2
++
++#define CONFIG_EXTRA_ENV_SETTINGS                                     \
++      "usbtty=cdc_acm\0"                                              \
++      "bootargs_base=rootfstype=jffs2 root=/dev/mtdblock4 console=ttySAC0,115200 console=tty0 loglevel=8\0" \
++      ""
++
++/*-----------------------------------------------------------------------
++ * Physical Memory Map
++ */
++#define CONFIG_NR_DRAM_BANKS  1          /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1          0x30000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE     0x08000000 /* 128 MB */
++#define PHYS_SDRAM_RES_SIZE   0x00200000 /* 2 MB for frame buffer */
++
++/*-----------------------------------------------------------------------
++ * FLASH and environment organization
++ */
++
++/* No NOR flash in this device */
++#define CFG_NO_FLASH          1
++
++#define       CFG_ENV_IS_IN_NAND      1
++#define CFG_ENV_SIZE          0x40000 /* 128k Total Size of Environment Sector */
++#define CFG_ENV_OFFSET_OOB    1       /* Location of ENV stored in block 0 OOB */
++#define       CFG_PREBOOT_OVERRIDE    1       /* allow preboot from memory */
++
++#define NAND_MAX_CHIPS                1
++#define CFG_NAND_BASE         0x4e000000
++#define CFG_MAX_NAND_DEVICE   1
++
++#define CONFIG_MMC            1
++#define CFG_MMC_BASE          0xff000000
++
++/* EXT2 driver */
++#define CONFIG_EXT2           1
++
++#define CONFIG_FAT            1
++#define CONFIG_SUPPORT_VFAT
++
++#if 1
++/* JFFS2 driver */
++#define CONFIG_JFFS2_CMDLINE  1
++#define CONFIG_JFFS2_NAND     1
++#define CONFIG_JFFS2_NAND_DEV 0
++//#define CONFIG_JFFS2_NAND_OFF       0x634000
++//#define CONFIG_JFFS2_NAND_SIZE      0x39cc000
++#endif
++
++/* ATAG configuration */
++#define CONFIG_INITRD_TAG             1
++#define CONFIG_SETUP_MEMORY_TAGS      1
++#define CONFIG_CMDLINE_TAG            1
++#define CONFIG_REVISION_TAG           1
++#if 0
++#define CONFIG_SERIAL_TAG             1
++#endif
++
++#define CONFIG_DRIVER_S3C24X0_I2C     1
++#define CONFIG_HARD_I2C                       1
++#define CFG_I2C_SPEED                 400000  /* 400kHz according to PCF50633 data sheet */
++#define CFG_I2C_SLAVE                 0x7f
++
++/* we have a board_late_init() function */
++#define BOARD_LATE_INIT                       1
++
++#if 0
++#define CONFIG_VIDEO
++#define CONFIG_VIDEO_S3C2410
++#define CONFIG_CFB_CONSOLE
++#define CONFIG_VIDEO_LOGO
++#define CONFIG_SPLASH_SCREEN
++#define CFG_VIDEO_LOGO_MAX_SIZE       (640*480+1024+100) /* 100 = slack */
++#define CONFIG_VIDEO_BMP_GZIP
++#define CONFIG_VGA_AS_SINGLE_DEVICE
++#define CONFIG_UNZIP
++
++#define VIDEO_KBD_INIT_FCT    0
++#define VIDEO_TSTC_FCT                serial_tstc
++#define VIDEO_GETC_FCT                serial_getc
++
++#define LCD_VIDEO_ADDR                0x33d00000
++#endif
++
++#define CONFIG_S3C2410_NAND_BBT                1
++//#define CONFIG_S3C2410_NAND_HWECC              1
++
++#define CONFIG_DRIVER_PCF50633                1
++
++#define MTDIDS_DEFAULT        "nand0=neo1973-nand"
++#define MTPARTS_DEFAULT       "neo1973-nand:256k(u-boot),128k(u-boot_env),2M(kernel),640k(splash),-(jffs2)"
++#define CFG_NAND_DYNPART_MTD_KERNEL_NAME "neo1973-nand"
++#define CONFIG_NAND_DYNPART
++
++#endif        /* __CONFIG_H */
+Index: u-boot/board/neo1973/gta02/split_by_variant.sh
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/gta02/split_by_variant.sh
+@@ -0,0 +1,37 @@
++#!/bin/sh
++# ---------------------------------------------------------
++#  Set the core module defines according to Core Module
++# ---------------------------------------------------------
++# ---------------------------------------------------------
++# Set up the GTA01 type define
++# ---------------------------------------------------------
++
++CFGINC=${obj}include/config.h
++CFGTMP=${obj}board/neo1973/gta02/config.tmp
++
++mkdir -p ${obj}include
++if [ "$1" == "" ]
++then
++      echo "$0:: No parameters - using GTA02Bv1 config"
++      echo "#define CONFIG_ARCH_GTA02_v1" > $CFGINC
++      echo "CONFIG_USB_DFU_REVISION=0x0310" > $CFGTMP
++else
++      case "$1" in
++      gta02v1_config)
++      echo "#define CONFIG_ARCH_GTA02_v1" > $CFGINC
++      echo "CONFIG_USB_DFU_REVISION=0x0310" > $CFGTMP
++      ;;
++
++      *)
++      echo "$0:: Unrecognised config - using GTA02v1 config"
++      echo "#define CONFIG_ARCH_GTA02_v1" > $CFGINC
++      echo "CONFIG_USB_DFU_REVISION=0x0310" > $CFGTMP
++      ;;
++
++      esac
++
++fi
++# ---------------------------------------------------------
++# Complete the configuration
++# ---------------------------------------------------------
++$MKCONFIG -a neo1973_gta02 arm arm920t gta02 neo1973 s3c24x0
+Index: u-boot/include/pcf50633.h
+===================================================================
+--- /dev/null
++++ u-boot/include/pcf50633.h
+@@ -0,0 +1,235 @@
++#ifndef _PCF50633_H
++#define _PCF50633_H
++
++/* Philips PCF50633 Power Managemnt Unit (PMU) driver
++ * (C) 2006-2007 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ */
++
++enum pfc50633_regs {
++      PCF50633_REG_VERSION    = 0x00,
++      PCF50633_REG_VARIANT    = 0x01,
++      PCF50633_REG_INT1       = 0x02, /* Interrupt Status */
++      PCF50633_REG_INT2       = 0x03, /* Interrupt Status */
++      PCF50633_REG_INT3       = 0x04, /* Interrupt Status */
++      PCF50633_REG_INT4       = 0x05, /* Interrupt Status */
++      PCF50633_REG_INT5       = 0x06, /* Interrupt Status */
++      PCF50633_REG_INT1M      = 0x07, /* Interrupt Mask */
++      PCF50633_REG_INT2M      = 0x08, /* Interrupt Mask */
++      PCF50633_REG_INT3M      = 0x09, /* Interrupt Mask */
++      PCF50633_REG_INT4M      = 0x0a, /* Interrupt Mask */
++      PCF50633_REG_INT5M      = 0x0b, /* Interrupt Mask */
++      PCF50633_REG_OOCSHDWN   = 0x0c,
++      PCF50633_REG_OOCWAKE    = 0x0d,
++      PCF50633_REG_OOCTIM1    = 0x0e,
++      PCF50633_REG_OOCTIM2    = 0x0f,
++      PCF50633_REG_OOCMODE    = 0x10,
++      PCF50633_REG_OOCCTL     = 0x11,
++      PCF50633_REG_OOCSTAT    = 0x12,
++      PCF50633_REG_GPIOCTL    = 0x13,
++      PCF50633_REG_GPIO1CFG   = 0x14,
++      PCF50633_REG_GPIO2CFG   = 0x15,
++      PCF50633_REG_GPIO3CFG   = 0x16,
++      PCF50633_REG_GPOCFG     = 0x17,
++      PCF50633_REG_BVMCTL     = 0x18,
++      PCF50633_REG_SVMCTL     = 0x19,
++      PCF50633_REG_AUTOOUT    = 0x1a,
++      PCF50633_REG_AUTOENA    = 0x1b,
++      PCF50633_REG_AUTOCTL    = 0x1c,
++      PCF50633_REG_AUTOMXC    = 0x1d,
++      PCF50633_REG_DOWN1OUT   = 0x1e,
++      PCF50633_REG_DOWN1ENA   = 0x1f,
++      PCF50633_REG_DOWN1CTL   = 0x20,
++      PCF50633_REG_DOWN1MXC   = 0x21,
++      PCF50633_REG_DOWN2OUT   = 0x22,
++      PCF50633_REG_DOWN2ENA   = 0x23,
++      PCF50633_REG_DOWN2CTL   = 0x24,
++      PCF50633_REG_DOWN2MXC   = 0x25,
++      PCF50633_REG_MEMLDOOUT  = 0x26,
++      PCF50633_REG_MEMLDOENA  = 0x27,
++      PCF50633_REG_LEDOUT     = 0x28,
++      PCF50633_REG_LEDENA     = 0x29,
++      PCF50633_REG_LEDCTL     = 0x2a,
++      PCF50633_REG_LEDDIM     = 0x2b,
++      /* reserved */
++      PCF50633_REG_LDO1OUT    = 0x2d,
++      PCF50633_REG_LDO1ENA    = 0x2e,
++      PCF50633_REG_LDO2OUT    = 0x2f,
++      PCF50633_REG_LDO2ENA    = 0x30,
++      PCF50633_REG_LDO3OUT    = 0x31,
++      PCF50633_REG_LDO3ENA    = 0x32,
++      PCF50633_REG_LDO4OUT    = 0x33,
++      PCF50633_REG_LDO4ENA    = 0x34,
++      PCF50633_REG_LDO5OUT    = 0x35,
++      PCF50633_REG_LDO5ENA    = 0x36,
++      PCF50633_REG_LDO6OUT    = 0x37,
++      PCF50633_REG_LDO6ENA    = 0x38,
++      PCF50633_REG_HCLDOOUT   = 0x39,
++      PCF50633_REG_HCLDOENA   = 0x3a,
++      PCF50633_REG_STBYCTL1   = 0x3b,
++      PCF50633_REG_STBYCTL2   = 0x3c,
++      PCF50633_REG_DEBPF1     = 0x3d,
++      PCF50633_REG_DEBPF2     = 0x3e,
++      PCF50633_REG_DEBPF3     = 0x3f,
++      PCF50633_REG_HCLDOOVL   = 0x40,
++      PCF50633_REG_DCDCSTAT   = 0x41,
++      PCF50633_REG_LDOSTAT    = 0x42,
++      PCF50633_REG_MBCC1      = 0x43,
++      PCF50633_REG_MBCC2      = 0x44,
++      PCF50633_REG_MBCC3      = 0x45,
++      PCF50633_REG_MBCC4      = 0x46,
++      PCF50633_REG_MBCC5      = 0x47,
++      PCF50633_REG_MBCC6      = 0x48,
++      PCF50633_REG_MBCC7      = 0x49,
++      PCF50633_REG_MBCC8      = 0x4a,
++      PCF50633_REG_MBCS1      = 0x4b,
++      PCF50633_REG_MBCS2      = 0x4c,
++      PCF50633_REG_MBCS3      = 0x4d,
++      PCF50633_REG_BBCCTL     = 0x4e,
++      PCF50633_REG_ALMGAIN    = 0x4f,
++      PCF50633_REG_ALMDATA    = 0x50,
++      /* reserved */
++      PCF50633_REG_ADCC3      = 0x52,
++      PCF50633_REG_ADCC2      = 0x53,
++      PCF50633_REG_ADCC1      = 0x54,
++      PCF50633_REG_ADCS1      = 0x55,
++      PCF50633_REG_ADCS2      = 0x56,
++      PCF50633_REG_ADCS3      = 0x57,
++      /* reserved */
++      PCF50633_REG_RTCSC      = 0x59, /* Second */
++      PCF50633_REG_RTCMN      = 0x5a, /* Minute */
++      PCF50633_REG_RTCHR      = 0x5b, /* Hour */
++      PCF50633_REG_RTCWD      = 0x5c, /* Weekday */
++      PCF50633_REG_RTCDT      = 0x5d, /* Day */
++      PCF50633_REG_RTCMT      = 0x5e, /* Month */
++      PCF50633_REG_RTCYR      = 0x5f, /* Year */
++      PCF50633_REG_RTCSCA     = 0x60, /* Alarm Second */
++      PCF50633_REG_RTCMNA     = 0x61, /* Alarm Minute */
++      PCF50633_REG_RTCHRA     = 0x62, /* Alarm Hour */
++      PCF50633_REG_RTCWDA     = 0x63, /* Alarm Weekday */
++      PCF50633_REG_RTCDTA     = 0x64, /* Alarm Day */
++      PCF50633_REG_RTCMTA     = 0x65, /* Alarm Month */
++      PCF50633_REG_RTCYRA     = 0x66, /* Alarm Year */
++
++      PCF50633_REG_MEMBYTE0   = 0x67,
++      PCF50633_REG_MEMBYTE1   = 0x68,
++      PCF50633_REG_MEMBYTE2   = 0x69,
++      PCF50633_REG_MEMBYTE3   = 0x6a,
++      PCF50633_REG_MEMBYTE4   = 0x6b,
++      PCF50633_REG_MEMBYTE5   = 0x6c,
++      PCF50633_REG_MEMBYTE6   = 0x6d,
++      PCF50633_REG_MEMBYTE7   = 0x6e,
++      /* reserved */
++      PCF50633_REG_DCDCPFM    = 0x84,
++      __NUM_PCF50633_REGS
++};
++
++enum pcf50633_reg_int1 {
++      PCF50633_INT1_ADPINS    = 0x01, /* Adapter inserted */
++      PCF50633_INT1_ADPREM    = 0x02, /* Adapter removed */
++      PCF50633_INT1_USBINS    = 0x04, /* USB inserted */
++      PCF50633_INT1_USBREM    = 0x08, /* USB removed */
++      /* reserved */
++      PCF50633_INT1_ALARM     = 0x40, /* RTC alarm time is reached */
++      PCF50633_INT1_SECOND    = 0x80, /* RTC periodic second interrupt */
++};
++
++enum pcf50633_reg_int2 {
++      PCF50633_INT2_ONKEYR    = 0x01, /* ONKEY rising edge */
++      PCF50633_INT2_ONKEYF    = 0x02, /* ONKEY falling edge */
++      PCF50633_INT2_EXTON1R   = 0x04, /* EXTON1 rising edge */
++      PCF50633_INT2_EXTON1F   = 0x08, /* EXTON1 falling edge */
++      PCF50633_INT2_EXTON2R   = 0x10, /* EXTON2 rising edge */
++      PCF50633_INT2_EXTON2F   = 0x20, /* EXTON2 falling edge */
++      PCF50633_INT2_EXTON3R   = 0x40, /* EXTON3 rising edge */
++      PCF50633_INT2_EXTON3F   = 0x80, /* EXTON3 falling edge */
++};
++
++enum pcf50633_reg_int3 {
++      PCF50633_INT3_BATFULL   = 0x01, /* Battery full */
++      PCF50633_INT3_CHGHALT   = 0x02, /* Charger halt */
++      PCF50633_INT3_THLIMON   = 0x04,
++      PCF50633_INT3_THLIMOFF  = 0x08,
++      PCF50633_INT3_USBLIMON  = 0x10,
++      PCF50633_INT3_USBLIMOFF = 0x20,
++      PCF50633_INT3_ADCRDY    = 0x40, /* ADC conversion finished */
++      PCF50633_INT3_ONKEY1S   = 0x80, /* ONKEY pressed 1 second */
++};
++
++enum pcf50633_reg_int4 {
++      PCF50633_INT4_LOWSYS            = 0x01,
++      PCF50633_INT4_LOWBAT            = 0x02,
++      PCF50633_INT4_HIGHTMP           = 0x04,
++      PCF50633_INT4_AUTOPWRFAIL       = 0x08,
++      PCF50633_INT4_DWN1PWRFAIL       = 0x10,
++      PCF50633_INT4_DWN2PWRFAIL       = 0x20,
++      PCF50633_INT4_LEDPWRFAIL        = 0x40,
++      PCF50633_INT4_LEDOVP            = 0x80,
++};
++
++enum pcf50633_reg_int5 {
++      PCF50633_INT4_LDO1PWRFAIL       = 0x01,
++      PCF50633_INT4_LDO2PWRFAIL       = 0x02,
++      PCF50633_INT4_LDO3PWRFAIL       = 0x04,
++      PCF50633_INT4_LDO4PWRFAIL       = 0x08,
++      PCF50633_INT4_LDO5PWRFAIL       = 0x10,
++      PCF50633_INT4_LDO6PWRFAIL       = 0x20,
++      PCF50633_INT4_HCLDOPWRFAIL      = 0x40,
++      PCF50633_INT4_HCLDOOVL          = 0x80,
++};
++
++enum pcf50633_reg_oocwake {
++      PCF50633_OOCWAKE_ONKEY          = 0x01,
++      PCF50633_OOCWAKE_EXTON1         = 0x02,
++      PCF50633_OOCWAKE_EXTON2         = 0x04,
++      PCF50633_OOCWAKE_EXTON3         = 0x08,
++      PCF50633_OOCWAKE_RTC            = 0x10,
++      /* reserved */
++      PCF50633_OOCWAKE_USB            = 0x40,
++      PCF50633_OOCWAKE_ADP            = 0x80,
++};
++
++enum pcf50633_reg_mbcc1 {
++      PCF50633_MBCC1_CHGENA           = 0x01, /* Charger enable */
++      PCF50633_MBCC1_AUTOSTOP         = 0x02,
++      PCF50633_MBCC1_AUTORES          = 0x04, /* automatic resume */
++      PCF50633_MBCC1_RESUME           = 0x08, /* explicit resume cmd */
++      PCF50633_MBCC1_RESTART          = 0x10, /* restart charging */
++      PCF50633_MBCC1_PREWDTIME_60M    = 0x20, /* max. precharging time */
++      PCF50633_MBCC1_WDTIME_1H        = 0x00,
++      PCF50633_MBCC1_WDTIME_2H        = 0x40,
++      PCF50633_MBCC1_WDTIME_4H        = 0x80,
++      PCF50633_MBCC1_WDTIME_6H        = 0xc0,
++};
++#define PCF50633_MBCC1_WDTIME_MASK      0xc0
++
++enum pcf50633_reg_mbcc2 {
++      PCF50633_MBCC2_VBATCOND_2V7     = 0x00,
++      PCF50633_MBCC2_VBATCOND_2V85    = 0x01,
++      PCF50633_MBCC2_VBATCOND_3V      = 0x02,
++      PCF50633_MBCC2_VBATCOND_3V15    = 0x03,
++      PCF50633_MBCC2_VMAX_4V          = 0x00,
++      PCF50633_MBCC2_VMAX_4V20        = 0x28,
++      PCF50633_MBCC2_VRESDEBTIME_64S  = 0x80, /* debounce time (32/64sec) */
++};
++#define       PCF50633_MBCC2_VBATCOND_MASK      0x03
++#define PCF50633_MBCC2_VMAX_MASK        0x3c
++
++#define PCF50633_OOCSTAT_ONKEY                0x01
++
++/* this is to be provided by the board implementation */
++extern const u_int8_t pcf50633_initial_regs[__NUM_PCF50633_REGS];
++
++void pcf50633_reg_write(u_int8_t reg, u_int8_t val);
++
++u_int8_t pcf50633_reg_read(u_int8_t reg);
++
++void pcf50633_reg_set_bit_mask(u_int8_t reg, u_int8_t mask, u_int8_t val);
++void pcf50633_reg_clear_bits(u_int8_t reg, u_int8_t bits);
++
++void pcf50633_init(void);
++void pcf50633_usb_maxcurrent(unsigned int ma);
++
++#endif /* _PCF50633_H */
++
+Index: u-boot/drivers/pcf50633.c
+===================================================================
+--- /dev/null
++++ u-boot/drivers/pcf50633.c
+@@ -0,0 +1,142 @@
++#include <common.h>
++
++#ifdef CONFIG_DRIVER_PCF50633
++
++#include <i2c.h>
++#include <pcf50633.h>
++#include <asm/atomic.h>
++#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
++
++#define PCF50633_I2C_ADDR             0x73
++
++void __pcf50633_reg_write(u_int8_t reg, u_int8_t val)
++{
++      i2c_write(PCF50633_I2C_ADDR, reg, 1, &val, 1);
++}
++
++u_int8_t __pcf50633_reg_read(u_int8_t reg)
++{
++      u_int8_t tmp;
++      i2c_read(PCF50633_I2C_ADDR, reg, 1, &tmp, 1);
++      return tmp;
++}
++
++void pcf50633_reg_write(u_int8_t reg, u_int8_t val)
++{
++      unsigned long flags;
++
++      local_irq_save(flags);
++      __pcf50633_reg_write(reg, val);
++      local_irq_restore(flags);
++}
++
++u_int8_t pcf50633_reg_read(u_int8_t reg)
++{
++      unsigned long flags;
++      u_int8_t tmp;
++
++      local_irq_save(flags);
++      tmp = __pcf50633_reg_read(reg);
++      local_irq_restore(flags);
++
++      return tmp;
++}
++
++void pcf50633_reg_set_bit_mask(u_int8_t reg, u_int8_t mask, u_int8_t val)
++{
++      unsigned long flags;
++      u_int8_t tmp;
++
++      local_irq_save(flags);
++      tmp = __pcf50633_reg_read(reg);
++      __pcf50633_reg_write(reg, (val & mask) | (tmp & ~mask));
++      local_irq_restore(flags);
++}
++
++void pcf50633_reg_clear_bits(u_int8_t reg, u_int8_t bits)
++{
++      unsigned long flags;
++      u_int8_t tmp;
++
++      local_irq_save(flags);
++      tmp = pcf50633_reg_read(reg);
++      pcf50633_reg_write(reg, (tmp & ~bits));
++      local_irq_restore(flags);
++}
++
++static const u_int8_t regs_invalid[] = {
++      PCF50633_REG_VERSION,
++      PCF50633_REG_VARIANT,
++      PCF50633_REG_OOCSHDWN,
++      PCF50633_REG_INT1,
++      PCF50633_REG_INT2,
++      PCF50633_REG_INT3,
++      PCF50633_REG_INT4,
++      PCF50633_REG_INT5,
++      PCF50633_REG_OOCSTAT,
++      0x2c,
++      PCF50633_REG_DCDCSTAT,
++      PCF50633_REG_LDOSTAT,
++      PCF50633_REG_MBCS1,
++      PCF50633_REG_MBCS2,
++      PCF50633_REG_MBCS3,
++      PCF50633_REG_ALMDATA,
++      0x51,
++      /* 0x55 ... 0x6e: don't write */
++      /* 0x6f ... 0x83: reserved */
++};
++#define PCF50633_LAST_REG     0x55
++
++static int reg_is_invalid(u_int8_t reg)
++{
++      int i;
++
++      /* all registers above 0x55 (ADCS1) except 0x84 */
++      if (reg == PCF50633_REG_DCDCPFM)
++              return 0;
++      if (reg >= 0x55)
++              return 1;
++
++      for (i = 0; i < ARRAY_SIZE(regs_invalid); i++) {
++              if (regs_invalid[i] > reg)
++                      return 0;
++              if (regs_invalid[i] == reg)
++                      return 1;
++      }
++
++      return 0;
++}
++
++
++/* initialize PCF50633 register set */
++void pcf50633_init(void)
++{
++      unsigned long flags;
++      u_int8_t i;
++
++      local_irq_save(flags);
++      for (i = 0; i < PCF50633_LAST_REG; i++) {
++              if (reg_is_invalid(i))
++                      continue;
++              __pcf50633_reg_write(i, pcf50633_initial_regs[i]);
++      }
++      local_irq_restore(flags);
++}
++
++void pcf50633_usb_maxcurrent(unsigned int ma)
++{
++      u_int8_t val;
++
++      if (ma < 100)
++              val = 0x03;
++      else if (ma < 500)
++              val = 0x00;
++      else if (ma < 1000)
++              val = 0x01;
++      else
++              val = 0x02;
++
++      return pcf50633_reg_set_bit_mask(PCF50633_REG_MBCC7, 0x03, val);
++}
++
++#endif /* CONFIG DRIVER_PCF50633 */
+Index: u-boot/board/neo1973/common/lowlevel_init.S
+===================================================================
+--- u-boot.orig/board/neo1973/common/lowlevel_init.S
++++ u-boot/board/neo1973/common/lowlevel_init.S
+@@ -49,7 +49,7 @@
+ #define WAIT                  (0x1<<2)
+ #define UBLB                  (0x1<<3)
+-#define B1_BWSCON             (DW32)
++#define B1_BWSCON             (DW16 + WAIT + UBLB)
+ #define B2_BWSCON             (DW16)
+ #define B3_BWSCON             (DW16 + WAIT + UBLB)
+ #define B4_BWSCON             (DW16)
+@@ -68,9 +68,9 @@
+ /* BANK1CON */
+ #define B1_Tacs                       0x0     /*  0clk */
+-#define B1_Tcos                       0x0     /*  0clk */
+-#define B1_Tacc                       0x7     /* 14clk */
+-#define B1_Tcoh                       0x0     /*  0clk */
++#define B1_Tcos                       0x1     /*  1clk */
++#define B1_Tacc                       0x4     /*  4clk */
++#define B1_Tcoh                       0x1     /*  1clk */
+ #define B1_Tah                        0x0     /*  0clk */
+ #define B1_Tacp                       0x0
+ #define B1_PMC                        0x0
+@@ -112,7 +112,7 @@
+ #if defined (CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
+ #define B6_SCAN                       0x1     /* 9bit */
+ #elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3) || \
+-      defined(CONFIG_ARCH_GTA01B_v4)
++      defined(CONFIG_ARCH_GTA01B_v4) || defined(CONFIG_ARCH_GTA02_v1)
+ #define B6_SCAN                       0x2     /* 10bit */
+ #endif
+@@ -165,6 +165,18 @@
+       str     r1, [r0]
+ #endif
++#if defined(CONFIG_ARCH_GTA02_v1)
++      /* enable KEEPACT to make sure PMU keeps us alive */
++      ldr     r0, =0x56000000 /* GPJ base */
++      ldr     r1, [r0, #0xd0] /* GPJCON */
++      orr     r1, r1, #(1 << 6)
++      str     r1, [r0, #0xd0]
++
++      ldr     r1, [r0, #0xd4] /* GPJDAT */
++      orr     r1, r1, #(1 << 3)
++      str     r1, [r0, #0xd4]
++#endif
++
+       /* everything is fine now */
+       mov     pc, lr
+Index: u-boot/board/neo1973/gta02/pcf50633.c
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/gta02/pcf50633.c
+@@ -0,0 +1,91 @@
++
++#include <common.h>
++#include <pcf50633.h>
++
++/* initial register set for PCF50633 in Neo1973 GTA02 devices */
++const u_int8_t pcf50633_initial_regs[__NUM_PCF50633_REGS] = {
++      /* gap */
++      [PCF50633_REG_INT1M]    = PCF50633_INT1_SECOND,
++      [PCF50633_REG_INT2M]    = PCF50633_INT2_EXTON3F |
++                                PCF50633_INT2_EXTON3R |
++                                PCF50633_INT2_EXTON2F |
++                                PCF50633_INT2_EXTON2R |
++                                PCF50633_INT2_EXTON1R |
++                                PCF50633_INT2_EXTON1F,
++      [PCF50633_REG_INT3M]    = PCF50633_INT3_ADCRDY,
++      [PCF50633_REG_INT4M]    = 0x00,
++      [PCF50633_REG_INT5M]    = 0x00,
++
++      [PCF50633_REG_OOCWAKE]  = 0xd3, /* wake from ONKEY,EXTON!,RTC,USB,ADP */
++      [PCF50633_REG_OOCTIM1]  = 0xaa, /* debounce 14ms everything */
++      [PCF50633_REG_OOCTIM2]  = 0x4a,
++      [PCF50633_REG_OOCMODE]  = 0x55,
++      [PCF50633_REG_OOCCTL]   = 0x44,
++
++      [PCF50633_REG_GPIOCTL]  = 0x01, /* only GPIO1 is input */
++      [PCF50633_REG_GPIO2CFG] = 0x00,
++      [PCF50633_REG_GPIO3CFG] = 0x00,
++      [PCF50633_REG_GPOCFG]   = 0x00,
++
++      [PCF50633_REG_SVMCTL]   = 0x08, /* 3.10V SYS voltage thresh. */
++      [PCF50633_REG_BVMCTL]   = 0x02, /* 2.80V BAT voltage thresh. */
++
++      [PCF50633_REG_STBYCTL1] = 0x00,
++      [PCF50633_REG_STBYCTL2] = 0x00,
++
++      [PCF50633_REG_DEBPF1]   = 0xff,
++      [PCF50633_REG_DEBPF2]   = 0xff,
++      [PCF50633_REG_DEBPF2]   = 0x3f,
++
++      [PCF50633_REG_AUTOOUT]  = 0x6b, /* 3.300V */
++      [PCF50633_REG_AUTOENA]  = 0x01, /* always on */
++      [PCF50633_REG_AUTOCTL]  = 0x00, /* automatic up/down operation */
++      [PCF50633_REG_AUTOMXC]  = 0x0a, /* 400mA at startup FIXME */
++
++      [PCF50633_REG_DOWN1OUT] = 0x1b, /* 1.3V (0x1b * .025V + 0.625V) */
++      [PCF50633_REG_DOWN1ENA] = 0x02, /* enabled if GPIO1 = HIGH */
++      [PCF50633_REG_DOWN1CTL] = 0x00, /* no DVM */
++      [PCF50633_REG_DOWN1MXC] = 0x22, /* limit to 510mA at startup */
++
++      [PCF50633_REG_DOWN2OUT] = 0x2f, /* 1.8V (0x2f * .025V + 0.625V) */
++      [PCF50633_REG_DOWN2ENA] = 0x02, /* enabled if GPIO1 = HIGH */
++      [PCF50633_REG_DOWN2CTL] = 0x00, /* no DVM */
++      [PCF50633_REG_DOWN2MXC] = 0x22, /* limit to 510mA at startup */
++
++      [PCF50633_REG_MEMLDOOUT] = 0x00,
++      [PCF50633_REG_MEMLDOENA] = 0x00,
++
++      [PCF50633_REG_LEDOUT]   = 0x2f, /* full backlight power */
++      [PCF50633_REG_LEDENA]   = 0x02, /* enabled if GPIO1 = HIGH */
++      [PCF50633_REG_LEDCTL]   = 0x05, /* ovp enabled, ocp 500mA */
++      [PCF50633_REG_LEDDIM]   = 0x20, /* dimming curve */
++
++      [PCF50633_REG_LDO1OUT]  = 0x04, /* 1.3V (4 * 0.1V + 0.9V) */
++      [PCF50633_REG_LDO1ENA]  = 0x01, /* always on */
++
++      [PCF50633_REG_LDO2OUT]  = 0x18, /* 3.3V (24 * 0.1V + 0.9V) */
++      [PCF50633_REG_LDO2ENA]  = 0x02, /* enabled if GPIO1 = HIGH */
++
++      [PCF50633_REG_LDO3OUT]  = 0x15, /* 3.0V (21 * 0.1V + 0.9V) */
++      [PCF50633_REG_LDO3ENA]  = 0x02, /* enabled if GPIO1 = HIGH */
++
++      [PCF50633_REG_LDO4ENA]  = 0x00,
++      [PCF50633_REG_LDO5ENA]  = 0x00,
++      [PCF50633_REG_LDO6ENA]  = 0x00,
++
++      [PCF50633_REG_HCLDOOUT] = 0x18, /* 3.3V (24 * 0.1V + 0.9V) */
++      [PCF50633_REG_HCLDOENA] = 0x00, /* off by default*/
++
++      [PCF50633_REG_DCDCPFM]  = 0x00, /* off by default*/
++
++      [PCF50633_REG_MBCC1]    = 0xe6,
++      [PCF50633_REG_MBCC2]    = 0x28, /* Vbatconid=2.7V, Vmax=4.20V */
++      [PCF50633_REG_MBCC3]    = 0x19, /* 25/255 == 98mA pre-charge */
++      [PCF50633_REG_MBCC4]    = 0xff, /* 255/255 == 1A adapter fast */
++      [PCF50633_REG_MBCC5]    = 0x7f, /* 127/255 == 500mA usb fast */
++      [PCF50633_REG_MBCC6]    = 0x00, /* cutoff current 1/32 * Ichg */
++      [PCF50633_REG_MBCC7]    = 0x00, /* 1.6A max bat curr, USB 100mA */
++      [PCF50633_REG_MBCC8]    = 0x00,
++
++      [PCF50633_REG_BBCCTL]   = 0x19, /* 3V, 200uA, on */
++};
+Index: u-boot/board/neo1973/gta02/config.mk
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/gta02/config.mk
+@@ -0,0 +1,32 @@
++#
++# (C) Copyright 2002
++# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
++# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++#
++# FIC Neo1973 GTA01 board with S3C2410X (ARM920T) cpu
++#
++# see http://www.samsung.com/ for more information on SAMSUNG
++#
++
++# GTA01v3 has 1 bank of 64 MB SDRAM
++# GTA01v4 has 1 bank of 64 MB SDRAM
++#
++#     3000'0000 to 3400'0000
++# we load ourself to 33F8'0000
++#
++# GTA01Bv2 or later has 1 bank of 128 MB SDRAM
++#
++#     3000'0000 to 3800'0000
++# we load ourself to 37F8'0000
++#
++# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
++# optionally with a ramdisk at 3080'0000
++#
++# download area is 3200'0000 or 3300'0000
++
++CONFIG_USB_DFU_VENDOR=0x1457
++CONFIG_USB_DFU_PRODUCT=0x5119
++
++sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
++
++TEXT_BASE = 0x33F80000
+Index: u-boot/drivers/smedia3362.c
+===================================================================
+--- /dev/null
++++ u-boot/drivers/smedia3362.c
+@@ -0,0 +1,125 @@
++/*
++ * (C) Copyright 2007 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * 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>
++
++#if defined(CONFIG_VIDEO_GLAMO3362)
++
++#include <video_fb.h>
++#include "videomodes.h"
++#include <s3c2410.h>
++#include "smedia3362.h"
++
++/*
++ * Export Graphic Device
++ */
++GraphicDevice smi;
++
++
++struct glamo_script {
++      u_int16_t reg;
++      u_int16_t val;
++} __attribute__((packed));
++
++/* from 'initial glamo 3365 script' */
++static struct glamo_script gl3362_init_script[] = {
++      /* clock */
++      { GLAMO_REG_CLOCK_MEMORY,       0x300a },
++      { GLAMO_REG_CLOCK_LCD,          0x10aa },
++      { GLAMO_REG_CLOCK_MMC,          0x100a },
++      { GLAMO_REG_CLOCK_ISP,          0x32aa },
++      { GLAMO_REG_CLOCK_JPEG,         0x100a },
++      { GLAMO_REG_CLOCK_3D,           0x302a },
++      { GLAMO_REG_CLOCK_2D,           0x302a },
++      //{ GLAMO_REG_CLOCK_RISC1,      0x1aaa },
++      //{ GLAMO_REG_CLOCK_RISC2,      0x002a },
++      { GLAMO_REG_CLOCK_MPEG,         0x3aaa },
++      { GLAMO_REG_CLOCK_MPROC,        0x12aa },
++              { 0xfffe, 5 },
++      { GLAMO_REG_CLOCK_HOST,         0x000d },
++      { GLAMO_REG_CLOCK_MEMORY,       0x000a }I,
++      { GLAMO_REG_CLOCK_LCD,          0x00ee },
++      { GLAMO_REG_CLOCK_MMC,          0x000a },
++      { GLAMO_REG_CLOCK_ISP,          0x02aa },
++      { GLAMO_REG_CLOCK_JPEG,         0x000a },
++      { GLAMO_REG_CLOCK_3D,           0x002a },
++      { GLAMO_REG_CLOCK_2D,           0x002a },
++      //{ GLAMO_REG_CLOCK_RISC1,      0x0aaa },
++      //{ GLAMO_REG_CLOCK_RISC2,      0x002a },
++      { GLAMO_REG_CLOCK_MPEG,         0x0aaa },
++      { GLAMO_REG_CLOCK_MPROC,        0x02aa },
++              { 0xfffe, 5 },
++      { GLAMO_REG_PLL_GEN1,           0x061a }, /* PLL1=50MHz, OSCI=32kHz */
++      { GLAMO_REG_PLL_GEN3,           0x09c3 }, /* PLL2=80MHz, OSCI=32kHz */
++              { 0xfffe, 5 },
++      { GLAMO_REG_CLOCK_GEN5_1,       0x18ff },
++      { GLAMO_REG_CLOCK_GEN5_2,       0x051f },
++      { GLAMO_REG_CLOCK_GEN6,         0x2000 },
++      { GLAMO_REG_CLOCK_GEN7,         0x0105 },
++      { GLAMO_REG_CLOCK_GEN8,         0x0100 },
++      { GLAMO_REG_CLOCK_GEN10,        0x0017 },
++      { GLAMO_REG_CLOCK_GEN11,        0x0017 },
++
++      /* hostbus interface */
++      { GLAMO_REG_HOSTBUS(1),         0x0e00 },
++      { GLAMO_REG_HOSTBUS(2),         0x07ff },
++      { GLAMO_REG_HOSTBUS(4),         0x0080 },
++      { GLAMO_REG_HOSTBUS(5),         0x0244 },
++      { GLAMO_REG_HOSTBUS(6),         0x0600 },
++      { GLAMO_REG_HOSTBUS(12),        0xf00e },
++
++      /* memory */
++      { GLAMO_REG_MEM_TYPE,           0x0874 }, /* VRAM 8Mbyte */
++      { GLAMO_REG_MEM_GEN,            0xafaf },
++      { GLAMO_REG_MEM_TIMING(1),      0x0108 },
++      { GLAMO_REG_MEM_TIMING(2),      0x0010 },
++      { GLAMO_REG_MEM_TIMING(3),      0x0000 },
++      { GLAMO_REG_MEM_TIMING(4),      0x0000 },
++      { GLAMO_REG_MEM_TIMING(5),      0x0000 },
++      { GLAMO_REG_MEM_TIMING(6),      0x0000 },
++      { GLAMO_REG_MEM_TIMING(7),      0x0000 },
++      { GLAMO_REG_MEM_TIMING(8),      0x1002 },
++      { GLAMO_REG_MEM_TIMING(9),      0x6006 },
++      { GLAMO_REG_MEM_TIMING(10),     0x00ff },
++      { GLAMO_REG_MEM_TIMING(11),     0x0001 },
++      { GLAMO_REG_MEM_POWER1,         0x0020 },
++      { GLAMO_REG_MEM_POWRE2,         0x0000 },
++      { GLAMO_REG_MEM_DRAM1,          0x0000 },
++              { 0xfffe, 1 },
++      { GLAMO_REG_MEM_DRAM1,          0xc100 },
++      { GLAMO_REG_MEM_DRAM2,          0x01d6 },
++};
++
++static int glamo3362_init(void)
++{
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(gl3362_init_script); i++) {
++              struct glamo_reg *reg = gl3362_init_script[i];
++
++              if (reg->reg == 0xfffe)
++                      delay(reg->val);
++              else
++                      gl3362_reg_write(reg->reg, reg->val);
++      }
++      /* FIXME */
++}
++
++#endif /* CONFIG_VIDEO_GLAMO3362 */
+Index: u-boot/drivers/Makefile
+===================================================================
+--- u-boot.orig/drivers/Makefile
++++ u-boot/drivers/Makefile
+@@ -50,7 +50,7 @@
+         usbdcore.o usbdfu.o usbdcore_ep0.o usbdcore_omap1510.o usbdcore_s3c2410.o usbtty.o \
+         videomodes.o w83c553f.o \
+         ks8695eth.o \
+-        pcf50606.o \
++        pcf50606.o pcf50633.o \
+         pxa_pcmcia.o mpc8xx_pcmcia.o tqm8xx_pcmcia.o  \
+         rpx_pcmcia.o \
+         fsl_i2c.o s3c2410_fb.o
+Index: u-boot/common/cmd_nand.c
+===================================================================
+--- u-boot.orig/common/cmd_nand.c
++++ u-boot/common/cmd_nand.c
+@@ -208,8 +208,10 @@
+               putc('\n');
+               for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
+                       if (nand_info[i].name)
+-                              printf("Device %d: %s, sector size %lu KiB\n",
++                              printf("Device %d: %s, page size %lu, "
++                                      "sector size %lu KiB\n",
+                                       i, nand_info[i].name,
++                                      nand_info[i].oobblock,
+                                       nand_info[i].erasesize >> 10);
+               }
+               return 0;
+Index: u-boot/drivers/nand/nand_ids.c
+===================================================================
+--- u-boot.orig/drivers/nand/nand_ids.c
++++ u-boot/drivers/nand/nand_ids.c
+@@ -67,7 +67,7 @@
+       {"NAND 256MiB 3,3V 8-bit",      0x71, 512, 256, 0x4000, 0},
+-      {"NAND 512MiB 3,3V 8-bit",      0xDC, 512, 512, 0x4000, 0},
++      //{"NAND 512MiB 3,3V 8-bit",    0xDC, 512, 512, 0x4000, 0},
+       /* These are the new chips with large page size. The pagesize
+       * and the erasesize is determined from the extended id bytes
+Index: u-boot/board/neo1973/common/udc.c
+===================================================================
+--- u-boot.orig/board/neo1973/common/udc.c
++++ u-boot/board/neo1973/common/udc.c
+@@ -3,6 +3,7 @@
+ #include <usbdcore.h>
+ #include <s3c2410.h>
+ #include <pcf50606.h>
++#include <pcf50633.h>
+ void udc_ctrl(enum usbd_event event, int param)
+ {
+@@ -23,6 +24,11 @@
+     defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3) || \
+     defined(CONFIG_ARCH_GTA01B_v4)
+               pcf50606_charge_autofast(param);
++#elif defined(CONFIG_ARCH_GTA02_v1)
++              if (param)
++                      pcf50633_usb_maxcurrent(500);
++              else
++                      pcf50633_usb_maxcurrent(0);
+ #endif
+               break;
+       default:
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-hxd8.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-hxd8.patch
new file mode 100644 (file)
index 0000000..f85fdea
--- /dev/null
@@ -0,0 +1,1169 @@
+Patch to add HXD8 support
+
+Index: u-boot/Makefile
+===================================================================
+--- u-boot.orig/Makefile
++++ u-boot/Makefile
+@@ -2026,6 +2026,9 @@
+ qt2410_config :       unconfig
+       @./mkconfig $(@:_config=) arm arm920t qt2410 NULL s3c24x0
++hxd8_config   :       unconfig
++      @$(MKCONFIG) $(@:_config=) arm arm920t hxd8 NULL s3c24x0
++
+ scb9328_config        :       unconfig
+       @$(MKCONFIG) $(@:_config=) arm arm920t scb9328 NULL imx
+Index: u-boot/board/hxd8/Makefile
+===================================================================
+--- /dev/null
++++ u-boot/board/hxd8/Makefile
+@@ -0,0 +1,65 @@
++#
++# (C) Copyright 2000-2006
++# Wolfgang Denk, DENX Software Engineering, wd@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
++#
++
++include $(TOPDIR)/config.mk
++
++LIB   = $(obj)lib$(BOARD).a
++
++COBJS := hxd8.o udc.o pcf50606.o
++SOBJS := lowlevel_init.o
++
++SRCS  := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS  := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++all:  $(LIB) lowevel_foo.bin
++
++$(LIB):       $(obj).depend $(OBJS) $(SOBJS)
++      $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
++
++lowlevel_foo.o:       lowlevel_foo.S
++      $(CC) -c -DTEXT_BASE=0x33F80000 -march=armv4 \
++        -o lowlevel_foo.o lowlevel_foo.S
++
++lowlevel_foo: lowlevel_foo.o lowlevel_init.o lowlevel_foo.lds
++      $(LD) -T ./lowlevel_foo.lds -Ttext 0x33f80000 -Bstatic \
++        lowlevel_init.o lowlevel_foo.o -o lowlevel_foo
++
++lowevel_foo.bin:      lowlevel_foo
++      $(CROSS_COMPILE)objcopy --gap-fill=0xff -O binary \
++        lowlevel_foo lowlevel_foo.bin
++
++clean:
++      rm -f $(SOBJS) $(OBJS)
++
++distclean:    clean
++      rm -f $(LIB) core *.bak .depend
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+Index: u-boot/board/hxd8/hxd8.c
+===================================================================
+--- /dev/null
++++ u-boot/board/hxd8/hxd8.c
+@@ -0,0 +1,189 @@
++/*
++ * (C) Copyright 2007 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Marius Groeger <mgroeger@sysgo.de>
++ *
++ * (C) Copyright 2002
++ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++ *
++ * 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 <video_fb.h>
++#include <nand.h>
++#include <pcf50606.h>
++#include <s3c2440.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#define FCLK_SPEED 1
++
++#if FCLK_SPEED==0             /* Fout = 203MHz, Fin = 12MHz for Audio */
++#define M_MDIV        0xC3
++#define M_PDIV        0x4
++#define M_SDIV        0x1
++#elif FCLK_SPEED==1
++#if 0
++#define M_MDIV        0x6e    /* Fout = 399.65MHz */
++#define M_PDIV        0x3
++#define M_SDIV        0x1
++#else
++#define M_MDIV        0x61    /* Fout = 296.35MHz due to wrong PLL capacitors */
++#define M_PDIV        0x1
++#define M_SDIV        0x2
++#endif
++#endif
++
++#define USB_CLOCK 1
++
++#if USB_CLOCK==0
++#define U_M_MDIV      0xA1
++#define U_M_PDIV      0x3
++#define U_M_SDIV      0x1
++#elif USB_CLOCK==1
++#define U_M_MDIV      0x3c
++#define U_M_PDIV      0x4
++#define U_M_SDIV      0x2
++#endif
++
++static inline void delay (unsigned long loops)
++{
++      __asm__ volatile ("1:\n"
++        "subs %0, %1, #1\n"
++        "bne 1b":"=r" (loops):"0" (loops));
++}
++
++/*
++ * Miscellaneous platform dependent initialisations
++ */
++
++int board_init (void)
++{
++      S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++      /* to reduce PLL lock time, adjust the LOCKTIME register */
++      clk_power->LOCKTIME = 0xFFFFFF;
++
++      /* configure MPLL */
++      clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
++
++      /* some delay between MPLL and UPLL */
++      delay (4000);
++
++      /* configure UPLL */
++      clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
++
++      /* some delay between MPLL and UPLL */
++      delay (8000);
++
++      /* set up the I/O ports */
++      gpio->GPACON = 0x005E0FFE;
++      gpio->GPADAT = 0x0001C000;
++      gpio->GPBCON = 0x00045542;
++      gpio->GPBUP = 0x000007FF;
++      gpio->GPCCON = 0xAAAA02A9;
++      gpio->GPCUP = 0x0000FFFF;
++      gpio->GPDCON = 0xAAAAAAAA;
++      gpio->GPDUP = 0x0000FFFF;
++      gpio->GPECON = 0xAAAAAAAA;
++      gpio->GPEUP = 0x0000FFFF;
++      gpio->GPFCON = 0x0000AAA9;
++      gpio->GPFUP = 0x000000FF;
++      gpio->GPGCON = 0x027D0316;
++      gpio->GPGUP = 0x0000FFFF;
++      gpio->GPHCON = 0x0014AAAA;
++      gpio->GPHUP = 0x000007FF;
++      gpio->GPJCON = 0x00000000;
++
++      /* USB CHG enable */
++      gpio->GPGDAT |= ( 1 << 11);
++#if 0
++      /* USB Device Part */
++      /*GPGCON is reset for USB Device */
++      gpio->GPGCON = (gpio->GPGCON & ~(3 << 24)) | (1 << 24); /* Output Mode */
++      gpio->GPGUP = gpio->GPGUP | ( 1 << 12);                 /* Pull up disable */
++
++      gpio->GPGDAT |= ( 1 << 12);
++      gpio->GPGDAT &= ~( 1 << 12);
++      udelay(20000);
++      gpio->GPGDAT |= ( 1 << 12);
++#endif
++
++      /* arch number of SMDK2440-Board */
++      gd->bd->bi_arch_number = MACH_TYPE_HXD8;
++
++      /* adress of boot parameters */
++      gd->bd->bi_boot_params = 0x30000100;
++
++      icache_enable();
++      dcache_enable();
++
++      return 0;
++}
++
++void board_video_init(GraphicDevice *pGD)
++{
++      S3C24X0_LCD * const lcd = S3C24X0_GetBase_LCD();
++
++      lcd->LCDCON1 = 0x0000057b;
++      lcd->LCDCON2 = 0x0143c049;
++      lcd->LCDCON3 = 0x0009df01;
++      lcd->LCDCON4 = 0x00000028;
++      lcd->LCDCON5 = 0x00000b08;
++
++      lcd->TPAL = 0x01202020;
++
++      //lcd->LCDCON5 |= (0x01 << 3);
++}
++
++int board_late_init(void)
++{
++      /* Initialize the Power Management Unit with a safe register set */
++      pcf50606_init();
++
++      return 0;
++}
++
++int dram_init(void)
++{
++      gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
++      gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
++
++      return 0;
++}
++
++u_int32_t get_board_rev(void)
++{
++      return 0x00000110;
++}
++
++/* The sum of all part_size[]s must equal to the NAND size, i.e., 0x4000000.
++   "initrd" is sized such that it can hold two uncompressed 16 bit 640*480
++   images: 640*480*2*2 = 1228800 < 1245184. */
++
++unsigned int dynpart_size[] = {
++    CFG_UBOOT_SIZE, 0x20000, 0x200000, 0xa0000, 0x3fd00000, 0 };
++char *dynpart_names[] = {
++    "u-boot", "u-boot_env", "kernel", "splash", "rootfs", NULL };
++
+Index: u-boot/board/hxd8/lowlevel_init.S
+===================================================================
+--- /dev/null
++++ u-boot/board/hxd8/lowlevel_init.S
+@@ -0,0 +1,171 @@
++/*
++ * Memory Setup stuff - taken from blob memsetup.S
++ *
++ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
++ *                     Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
++ *
++ * Modified for the FIC HXD8 by Harald Welte <laforge@openmoko.org>
++ * (C) Copyright 2007 by OpenMoko, Inc.
++ *
++ * 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 <version.h>
++
++
++/* some parameters for the board */
++
++/*
++ *
++ * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
++ *
++ * Copyright (C) 2002 Samsung Electronics SW.LEE  <hitchcar@sec.samsung.com>
++ *
++ */
++
++#define BWSCON        0x48000000
++
++/* BWSCON */
++#define DW8                   (0x0)
++#define DW16                  (0x1)
++#define DW32                  (0x2)
++#define WAIT                  (0x1<<2)
++#define UBLB                  (0x1<<3)
++
++#define B1_BWSCON             (DW32)
++#define B2_BWSCON             (DW16)
++#define B3_BWSCON             (DW16 + WAIT + UBLB)
++#define B4_BWSCON             (DW16)
++#define B5_BWSCON             (DW16)
++#define B6_BWSCON             (DW32)
++#define B7_BWSCON             (DW32)
++
++/* BANK0CON */
++#define B0_Tacs                       0x0     /*  0clk */
++#define B0_Tcos                       0x0     /*  0clk */
++#define B0_Tacc                       0x7     /* 14clk */
++#define B0_Tcoh                       0x0     /*  0clk */
++#define B0_Tah                        0x0     /*  0clk */
++#define B0_Tacp                       0x0
++#define B0_PMC                        0x0     /* normal */
++
++/* BANK1CON */
++#define B1_Tacs                       0x0     /*  0clk */
++#define B1_Tcos                       0x0     /*  0clk */
++#define B1_Tacc                       0x7     /* 14clk */
++#define B1_Tcoh                       0x0     /*  0clk */
++#define B1_Tah                        0x0     /*  0clk */
++#define B1_Tacp                       0x0
++#define B1_PMC                        0x0
++
++#define B2_Tacs                       0x0
++#define B2_Tcos                       0x0
++#define B2_Tacc                       0x7
++#define B2_Tcoh                       0x0
++#define B2_Tah                        0x0
++#define B2_Tacp                       0x0
++#define B2_PMC                        0x0
++
++#define B3_Tacs                       0x0     /*  0clk */
++#define B3_Tcos                       0x3     /*  4clk */
++#define B3_Tacc                       0x7     /* 14clk */
++#define B3_Tcoh                       0x1     /*  1clk */
++#define B3_Tah                        0x0     /*  0clk */
++#define B3_Tacp                       0x3     /*  6clk */
++#define B3_PMC                        0x0     /* normal */
++
++#define B4_Tacs                       0x0     /*  0clk */
++#define B4_Tcos                       0x0     /*  0clk */
++#define B4_Tacc                       0x7     /* 14clk */
++#define B4_Tcoh                       0x0     /*  0clk */
++#define B4_Tah                        0x0     /*  0clk */
++#define B4_Tacp                       0x0
++#define B4_PMC                        0x0     /* normal */
++
++#define B5_Tacs                       0x0     /*  0clk */
++#define B5_Tcos                       0x0     /*  0clk */
++#define B5_Tacc                       0x7     /* 14clk */
++#define B5_Tcoh                       0x0     /*  0clk */
++#define B5_Tah                        0x0     /*  0clk */
++#define B5_Tacp                       0x0
++#define B5_PMC                        0x0     /* normal */
++
++#define B6_MT                 0x3     /* SDRAM */
++#define B6_Trcd                       0x1     /* 3clk */
++#define B6_SCAN                       0x2     /* 10bit */
++
++#define B7_MT                 0x3     /* SDRAM */
++#define B7_Trcd                       0x1     /* 3clk */
++#define B7_SCAN                       0x1     /* 9bit */
++
++/* REFRESH parameter */
++#define REFEN                 0x1     /* Refresh enable */
++#define TREFMD                        0x0     /* CBR(CAS before RAS)/Auto refresh */
++#define Trp                   0x1     /* 3clk */
++#define Trc                   0x3     /* 7clk */
++#define Tchr                  0x2     /* 3clk */
++#define REFCNT                        1113    /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
++/**************************************/
++
++_TEXT_BASE:
++      .word   TEXT_BASE
++
++.globl lowlevel_init
++lowlevel_init:
++      /* memory control configuration */
++      /* make r0 relative the current location so that it */
++      /* reads SMRDATA out of FLASH rather than memory ! */
++      ldr     r0, =SMRDATA
++      ldr     r1, _TEXT_BASE
++      sub     r0, r0, r1
++      ldr     r1, =BWSCON     /* Bus Width Status Controller */
++      add     r2, r0, #13*4
++0:
++      ldr     r3, [r0], #4
++      str     r3, [r1], #4
++      cmp     r2, r0
++      bne     0b
++
++      /* setup asynchronous bus mode */
++      mrc     p15, 0, r1 ,c1 ,c0, 0
++      orr     r1, r1, #0xc0000000
++      mcr     p15, 0, r1, c1, c0, 0
++
++      /* everything is fine now */
++      mov     pc, lr
++
++      .ltorg
++/* the literal pools origin */
++
++SMRDATA:
++    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
++    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
++    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
++    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
++    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
++    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
++    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
++    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
++    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
++    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
++    .word 0x32
++    .word 0x30
++    .word 0x30
+Index: u-boot/include/configs/hxd8.h
+===================================================================
+--- /dev/null
++++ u-boot/include/configs/hxd8.h
+@@ -0,0 +1,277 @@
++/*
++ * (C) Copyright 2007 OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * Configuation settings for the FIC HXD8
++ *
++ * 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
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/* we want to be able to start u-boot directly from within NAND flash */
++#define CONFIG_LL_INIT_NAND_ONLY
++#define CONFIG_S3C2410_NAND_BOOT      1
++#define CONFIG_S3C2410_NAND_SKIP_BAD  1
++
++#define CFG_UBOOT_SIZE                0x40000 /* size of u-boot, for NAND loading */
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++#define CONFIG_ARM920T                1       /* This is an ARM920T Core      */
++#define       CONFIG_S3C2440          1       /* in a SAMSUNG S3C2440 SoC     */
++#define CONFIG_SMDK2440               1       /* on a SAMSUNG SMDK2440 Board  */
++#define CONFIG_HXD8           1       /* on a FIC HXD8 Board  */
++
++/* input clock of PLL */
++#define CONFIG_SYS_CLK_FREQ   16934400/* the HXD8 has this input clock */
++
++
++#define USE_920T_MMU          1
++#define CONFIG_USE_IRQ                1
++
++/*
++ * Size of malloc() pool
++ */
++#define CFG_MALLOC_LEN                (CFG_ENV_SIZE + 2048*1024)
++                                      /* >> CFG_VIDEO_LOGO_MAX_SIZE */
++#define CFG_GBL_DATA_SIZE     128     /* size in bytes reserved for initial data */
++
++/*
++ * Hardware drivers
++ */
++
++/*
++ * select serial console configuration
++ */
++#define CONFIG_SERIAL3                1       /* we use SERIAL 3 on HXD8 */
++
++/************************************************************
++ * RTC
++ ************************************************************/
++#define       CONFIG_RTC_S3C24X0      1
++
++/* allow to overwrite serial and ethaddr */
++#define CONFIG_ENV_OVERWRITE
++
++#define CONFIG_BAUDRATE               115200
++
++/***********************************************************
++ * Command definition
++ ***********************************************************/
++#define CONFIG_COMMANDS (\
++                      CFG_CMD_BDI      | \
++                      CFG_CMD_LOADS    | \
++                      CFG_CMD_LAODB    | \
++                      CFG_CMD_IMI      | \
++                      CFG_CMD_CACHE    | \
++                      CFG_CMD_MEMORY   | \
++                      CFG_CMD_ENV      | \
++                      /* CFG_CMD_IRQ   | */  \
++                      CFG_CMD_BOOTD    | \
++                      CFG_CMD_CONSOLE  | \
++                      /* CFG_CMD_BMP   | */ \
++                      CFG_CMD_ASKENV   | \
++                      CFG_CMD_RUN      | \
++                      CFG_CMD_ECHO     | \
++                      CFG_CMD_I2C      | \
++                      CFG_CMD_REGINFO  | \
++                      CFG_CMD_IMMAP    | \
++                      CFG_CMD_DATE     | \
++                      CFG_CMD_AUTOSCRIPT | \
++                      CFG_CMD_BSP      | \
++                      CFG_CMD_ELF      | \
++                      CFG_CMD_MISC     | \
++                      /* CFG_CMD_USB   | */ \
++                      CFG_CMD_JFFS2    | \
++                      CFG_CMD_DIAG     | \
++                      /* CFG_CMD_HWFLOW        | */ \
++                      CFG_CMD_SAVES    | \
++                      CFG_CMD_NAND     | \
++                      CFG_CMD_PORTIO   | \
++                      CFG_CMD_MMC      | \
++                      CFG_CMD_FAT      | \
++                      CFG_CMD_EXT2     | \
++                      0)
++/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
++#include <cmd_confdefs.h>
++
++#define CONFIG_BOOTDELAY      3
++#define CONFIG_BOOTARGS       ""
++#define CONFIG_BOOTCOMMAND    "setenv bootargs ${bootargs_base} ${mtdparts}; nand read.e 0x32000000 kernel; bootm 0x32000000"
++
++#define CONFIG_DOS_PARTITION  1
++
++#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
++#define CONFIG_KGDB_BAUDRATE  115200          /* speed to run kgdb serial port */
++/* what's this ? it's not used anywhere */
++#define CONFIG_KGDB_SER_INDEX 3               /* which serial port to use */
++#endif
++
++/*
++ * Miscellaneous configurable options
++ */
++#define       CFG_LONGHELP                            /* undef to save memory         */
++#define       CFG_PROMPT              "HXD8 # "       /* Monitor Command Prompt       */
++#define       CFG_CBSIZE              256             /* Console I/O Buffer Size      */
++#define       CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
++#define       CFG_MAXARGS             64              /* max number of command args   */
++#define CFG_BARGSIZE          CFG_CBSIZE      /* Boot Argument Buffer Size    */
++
++#define CFG_MEMTEST_START     0x30000000      /* memtest works on     */
++#define CFG_MEMTEST_END               0x33F00000      /* 63 MB in DRAM        */
++
++#undef  CFG_CLKS_IN_HZ                /* everything, incl board info, in Hz */
++
++#define       CFG_LOAD_ADDR           0x33000000      /* default load address */
++
++/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
++/* it to wrap 100 times (total 1562500) to get 1 sec. */
++#define       CFG_HZ                  1562500
++
++/* valid baudrates */
++#define CFG_BAUDRATE_TABLE    { 9600, 19200, 38400, 57600, 115200 }
++
++/*-----------------------------------------------------------------------
++ * Stack sizes
++ *
++ * The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE      (512*1024)      /* regular stack */
++#ifdef CONFIG_USE_IRQ
++#define CONFIG_STACKSIZE_IRQ  (8*1024)        /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ  (4*1024)        /* FIQ stack */
++#endif
++
++#if 0
++#define CONFIG_USB_OHCI               1
++#endif
++
++#if 1
++#define CONFIG_USB_DEVICE     1
++#define CONFIG_USB_TTY                1
++#define CFG_CONSOLE_IS_IN_ENV 1
++#define CONFIG_USBD_VENDORID          0x1457     /* Linux/NetChip */
++#define CONFIG_USBD_PRODUCTID_GSERIAL 0x5120    /* gserial */
++#define CONFIG_USBD_PRODUCTID_CDCACM  0x511a    /* CDC ACM */
++#define CONFIG_USBD_MANUFACTURER      "OpenMoko, Inc"
++#define CONFIG_USBD_PRODUCT_NAME      "HXD8 Bootloader " U_BOOT_VERSION
++#define CONFIG_USBD_DFU                       1
++#define CONFIG_USBD_DFU_XFER_SIZE     4096    /* 0x4000 */
++#define CONFIG_USBD_DFU_INTERFACE     2
++#endif
++#define CFG_CONSOLE_IS_IN_ENV 1
++
++#define CONFIG_EXTRA_ENV_SETTINGS                                     \
++      "usbtty=cdc_acm\0"                                              \
++      "bootargs_base=rootfstype=jffs2 root=/dev/mtdblock4 console=ttySAC2,115200 console=tty0 loglevel=8\0" \
++      ""
++
++/*-----------------------------------------------------------------------
++ * Physical Memory Map
++ */
++#define CONFIG_NR_DRAM_BANKS  1          /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1          0x30000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE     0x08000000 /* 128 MB */
++#define PHYS_SDRAM_RES_SIZE   0x00200000 /* 2 MB for frame buffer */
++
++/*-----------------------------------------------------------------------
++ * FLASH and environment organization
++ */
++
++/* No NOR flash in this device */
++#define CFG_NO_FLASH          1
++
++#define CFG_ENV_SIZE          0x20000         /* 128k Total Size of Environment Sector */
++#define       CFG_ENV_IS_IN_NAND      1
++#define CFG_ENV_OFFSET_OOB    1               /* Location of ENV stored in block 0 OOB */
++#define       CFG_PREBOOT_OVERRIDE    1       /* allow preboot from memory */
++
++#define NAND_MAX_CHIPS                3
++#define CFG_NAND_BASE         0x4e000000
++#define CFG_MAX_NAND_DEVICE   NAND_MAX_CHIPS
++#define CFG_NAND_BASE_LIST    { CFG_NAND_BASE, CFG_NAND_BASE, CFG_NAND_BASE }
++
++#define CONFIG_MMC            1
++#define CFG_MMC_BASE          0xff000000
++
++/* EXT2 driver */
++#define CONFIG_EXT2           1
++
++#define CONFIG_FAT            1
++#define CONFIG_SUPPORT_VFAT
++
++#if 1
++/* JFFS2 driver */
++#define CONFIG_JFFS2_CMDLINE  1
++#define CONFIG_JFFS2_NAND     1
++#define CONFIG_JFFS2_NAND_DEV 0
++//#define CONFIG_JFFS2_NAND_OFF       0x634000
++//#define CONFIG_JFFS2_NAND_SIZE      0x39cc000
++#endif
++
++/* ATAG configuration */
++#define CONFIG_INITRD_TAG             1
++#define CONFIG_SETUP_MEMORY_TAGS      1
++#define CONFIG_CMDLINE_TAG            1
++#define CONFIG_REVISION_TAG           1
++#if 0
++#define CONFIG_SERIAL_TAG             1
++#endif
++
++#define CONFIG_DRIVER_S3C24X0_I2C     1
++#define CONFIG_HARD_I2C                       1
++#define CFG_I2C_SPEED                 400000  /* 400kHz according to PCF50606 data sheet */
++#define CFG_I2C_SLAVE                 0x7f
++
++/* we have a board_late_init() function */
++#define BOARD_LATE_INIT                       1
++
++#if 1
++#define CONFIG_VIDEO
++#define CONFIG_VIDEO_S3C2410
++#define CONFIG_CFB_CONSOLE
++#define CONFIG_VIDEO_LOGO
++#define CONFIG_SPLASH_SCREEN
++#define CFG_VIDEO_LOGO_MAX_SIZE       (640*480+1024+100) /* 100 = slack */
++#define CONFIG_VIDEO_BMP_GZIP
++#define CONFIG_VGA_AS_SINGLE_DEVICE
++#define CONFIG_UNZIP
++
++#define VIDEO_KBD_INIT_FCT    0
++#define VIDEO_TSTC_FCT                serial_tstc
++#define VIDEO_GETC_FCT                serial_getc
++
++#define LCD_VIDEO_ADDR                0x33d00000
++#endif
++
++#define CONFIG_S3C2410_NAND_BBT                1
++//#define CONFIG_S3C2410_NAND_HWECC              1
++
++#define CONFIG_DRIVER_PCF50606                1
++
++#define MTDIDS_DEFAULT        "nand0=hxd8-nand"
++#define MTPARTS_DEFAULT       "hxd8-nand:256k(u-boot),128k(u-boot_env),2M(kernel),640k(splash),0x3fd00000(jffs2)"
++#define CFG_NAND_DYNPART_MTD_KERNEL_NAME "hxd8-nand"
++#define CONFIG_NAND_DYNPART
++
++#endif        /* __CONFIG_H */
+Index: u-boot/board/hxd8/udc.c
+===================================================================
+--- /dev/null
++++ u-boot/board/hxd8/udc.c
+@@ -0,0 +1,30 @@
++
++#include <common.h>
++#include <usbdcore.h>
++#include <s3c2440.h>
++
++#if defined(CONFIG_USB_DEVICE)
++
++void udc_ctrl(enum usbd_event event, int param)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++      switch (event) {
++      case UDC_CTRL_PULLUP_ENABLE:
++              if (param)
++                      gpio->GPBDAT |= (1 << 9);       /* GPB9 */
++              else
++                      gpio->GPBDAT &= ~(1 << 9);      /* GPB9 */
++              break;
++      case UDC_CTRL_500mA_ENABLE:
++              if (param)
++                      gpio->GPADAT |= (1 << 0);       /* GPA0 */
++              else
++                      gpio->GPADAT &= ~(1 << 0);      /* GPA0 */
++              break;
++      default:
++              break;
++      }
++}
++
++#endif /* CONFIG_USB_DEVICE */
+Index: u-boot/board/hxd8/pcf50606.c
+===================================================================
+--- /dev/null
++++ u-boot/board/hxd8/pcf50606.c
+@@ -0,0 +1,67 @@
++
++#include <common.h>
++#include <pcf50606.h>
++
++/* initial register set for PCF50606 in HXD8 devices */
++const u_int8_t pcf50606_initial_regs[__NUM_PCF50606_REGS] = {
++      [PCF50606_REG_OOCS]     = 0x00,
++      /* gap */
++      [PCF50606_REG_INT1M]    = PCF50606_INT1_SECOND,
++      [PCF50606_REG_INT2M]    = PCF50606_INT2_CHGFOK |
++                                PCF50606_INT2_CHGERR |
++                                PCF50606_INT2_CHGFRDY |
++                                PCF50606_INT2_CHGPROT |
++                                PCF50606_INT2_CHGWD10S |
++                                PCF50606_INT2_CHGWDEXP,
++      [PCF50606_REG_INT3M]    = PCF50606_INT3_TSCPRES,
++      [PCF50606_REG_OOCC1]    = PCF50606_OOCC1_RTCWAK |
++                                PCF50606_OOCC1_CHGWAK &
++                                PCF50606_OOCC1_EXTONWAK_NO_WAKEUP,
++      [PCF50606_REG_OOCC2]    = PCF50606_OOCC2_ONKEYDB_14ms |
++                                PCF50606_OOCC2_EXTONDB_14ms,
++      /* gap */
++      [PCF50606_REG_PSSC]     = 0x00,
++      [PCF50606_REG_PWROKM]   = 0x00,
++      /* gap */
++      [PCF50606_REG_DCDC1]    = 0xf0, /* CORE_1V3: on */
++      [PCF50606_REG_DCDC2]    = 0x00,
++      [PCF50606_REG_DCDC3]    = 0x00,
++      [PCF50606_REG_DCDC4]    = 0x30, /* 1.25A */
++
++      [PCF50606_REG_DCDEC1]   = 0xe8, /* IO1_3V3: off */
++      [PCF50606_REG_DCDEC2]   = 0x00,
++
++      [PCF50606_REG_DCUDC1]   = 0x08, /* RF_3V3: off */
++      [PCF50606_REG_DCUDC2]   = 0x30, /* 1.25A current limit */
++
++      [PCF50606_REG_IOREGC]   = 0xf8, /* AUDIO_3V3: on */
++
++      [PCF50606_REG_D1REGC1]  = 0xf8, /* RC_3V3: on */
++
++      [PCF50606_REG_D2REGC1]  = 0x18, /* GPS_3V3: off */
++
++      [PCF50606_REG_D3REGC1]  = 0xf8, /* IO2_3V3: off */
++
++      [PCF50606_REG_LPREGC1]  = 0xf8, /* LCM_3V3: on */
++      [PCF50606_REG_LPREGC2]  = 0x00,
++
++      [PCF50606_REG_MBCC1]    = 0x00, /* charger unused */
++      [PCF50606_REG_MBCC2]    = 0x00, /* unlimited charging */
++      [PCF50606_REG_MBCC3]    = 0x1a, /* 0.2*Ifast, 4.20V */
++      [PCF50606_REG_BBCC]     = 0x1f, /* 400uA */
++      [PCF50606_REG_ADCC1]    = 0x00,
++      [PCF50606_REG_ADCC2]    = 0x00,
++      /* gap */
++      [PCF50606_REG_ACDC1]    = 0x00,
++      [PCF50606_REG_BVMC]     = PCF50606_BVMC_THRSHLD_3V3,
++      [PCF50606_REG_PWMC1]    = 0x1f, /* clock: 512 DC: 15/16*/
++      [PCF50606_REG_LEDC1]    = 0x00,
++      [PCF50606_REG_LEDC2]    = 0x00,
++      [PCF50606_REG_GPOC1]    = 0x03, /* PWM ACTIVE */
++      [PCF50606_REG_GPOC2]    = 0x07, /* back light pull low */
++      [PCF50606_REG_GPOC3]    = 0x00,
++      [PCF50606_REG_GPOC4]    = 0x00,
++      [PCF50606_REG_GPOC5]    = 0x00,
++};
++
++
+Index: u-boot/board/hxd8/config.mk
+===================================================================
+--- /dev/null
++++ u-boot/board/hxd8/config.mk
+@@ -0,0 +1,27 @@
++#
++# (C) Copyright 2002
++# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
++# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++#
++# FIC HXD8 board with S3C2440X (ARM920T) cpu
++#
++# see http://www.samsung.com/ for more information on SAMSUNG
++#
++
++CONFIG_USB_DFU_VENDOR=0x1457
++CONFIG_USB_DFU_PRODUCT=0x511a
++CONFIG_USB_DFU_REVISION=0x0100
++
++#
++# HXD81v011 or later has 1 bank of 128 MB SDRAM
++#
++#     3000'0000 to 3800'0000
++# we load ourself to 37F8'0000
++#
++# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
++# optionally with a ramdisk at 3080'0000
++#
++# download area is 3200'0000 or 3300'0000
++
++# FIXME: TEXT_BASE = 0x37F80000
++TEXT_BASE = 0x33F80000
+Index: u-boot/board/hxd8/u-boot.lds
+===================================================================
+--- /dev/null
++++ u-boot/board/hxd8/u-boot.lds
+@@ -0,0 +1,58 @@
++/*
++ * (C) Copyright 2002
++ * Gary Jennejohn, DENX Software Engineering, <gj@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_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
++OUTPUT_ARCH(arm)
++ENTRY(_start)
++SECTIONS
++{
++      . = 0x00000000;
++
++      . = ALIGN(4);
++      .text      :
++      {
++        cpu/arm920t/start.o   (.text)
++        cpu/arm920t/s3c24x0/nand_read.o (.text)
++        *(.text)
++      }
++
++      . = ALIGN(4);
++      .rodata : { *(.rodata) }
++
++      . = ALIGN(4);
++      .data : { *(.data) }
++
++      . = ALIGN(4);
++      .got : { *(.got) }
++
++      . = .;
++      __u_boot_cmd_start = .;
++      .u_boot_cmd : { *(.u_boot_cmd) }
++      __u_boot_cmd_end = .;
++
++      . = ALIGN(4);
++      __bss_start = .;
++      .bss : { *(.bss) }
++      _end = .;
++}
+Index: u-boot/board/hxd8/lowlevel_foo.S
+===================================================================
+--- /dev/null
++++ u-boot/board/hxd8/lowlevel_foo.S
+@@ -0,0 +1,87 @@
++
++_start:
++      b       reset
++undefvec:
++      b       undefvec
++swivec:
++      b       swivec
++pabtvec:
++      b       pabtvec
++dabtvec:
++      b       dabtvec
++rsvdvec:
++      b       rsvdvec
++irqvec:
++      b       irqvec
++fiqvec:
++      b       fiqvec
++
++reset:
++      /*
++       * set the cpu to SVC32 mode
++       */
++      mrs     r0,cpsr
++      bic     r0,r0,#0x1f
++      orr     r0,r0,#0xd3
++      msr     cpsr,r0
++
++/* turn off the watchdog */
++#define pWTCON                0x53000000
++#define INTMSK                0x4A000008      /* Interupt-Controller base addresses */
++#define INTSUBMSK     0x4A00001C
++#define CLKDIVN       0x4C000014      /* clock divisor register */
++#define CAMDIVN       0x4C000018
++
++      ldr     r0, =pWTCON
++      mov     r1, #0x0
++      str     r1, [r0]
++
++      mov     r1, #0xffffffff
++      ldr     r0, =INTMSK
++      str     r1, [r0]
++      ldr     r1, =0x7ff
++      ldr     r0, =INTSUBMSK
++      str     r1, [r0]
++
++      /* FCLK:HCLK:PCLK = 1:3:6 */
++      ldr     r0, =CAMDIVN
++      mov     r1, #0
++      str     r1, [r0]
++
++      /* FCLK:HCLK:PCLK = 1:3:6 */
++      ldr     r0, =CLKDIVN
++      mov     r1, #7
++      str     r1, [r0]
++
++      bl      cpu_init_crit
++      ldr     r0,=TEXT_BASE
++      mov     pc, r0
++
++cpu_init_crit:
++      /*
++       * flush v4 I/D caches
++       */
++      mov     r0, #0
++      mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
++      mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
++
++      /*
++       * 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
++
++      /*
++       * before relocating, we have to setup RAM timing
++       * because memory timing is board-dependend, you will
++       * find a lowlevel_init.S in your board directory.
++       */
++      mov     ip, lr
++      bl      lowlevel_init
++      mov     lr, ip
++      mov     pc, lr
++
+Index: u-boot/board/hxd8/lowlevel_foo.lds
+===================================================================
+--- /dev/null
++++ u-boot/board/hxd8/lowlevel_foo.lds
+@@ -0,0 +1,56 @@
++/*
++ * (C) Copyright 2002
++ * Gary Jennejohn, DENX Software Engineering, <gj@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      :
++      {
++        lowlevel_foo.o (.text)
++        *(.text)
++      }
++
++      . = ALIGN(4);
++      .rodata : { *(.rodata) }
++
++      . = ALIGN(4);
++      .data : { *(.data) }
++
++      . = ALIGN(4);
++      .got : { *(.got) }
++
++      . = .;
++      __u_boot_cmd_start = .;
++      .u_boot_cmd : { *(.u_boot_cmd) }
++      __u_boot_cmd_end = .;
++
++      . = ALIGN(4);
++      __bss_start = .;
++      .bss : { *(.bss) }
++      _end = .;
++}
+Index: u-boot/cpu/arm920t/s3c24x0/nand.c
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/nand.c
++++ u-boot/cpu/arm920t/s3c24x0/nand.c
+@@ -83,6 +83,59 @@
+ #define       NFDATA          __REGb(NF_BASE + oNFDATA)
+ #define       NFSTAT          __REGb(NF_BASE + oNFSTAT)
++#if defined(CONFIG_HXD8)
++static int hxd8_nand_dev_ready(struct mtd_info *mtd)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++      u_int32_t val = gpio->GPCDAT;
++
++      switch (nand_curr_device) {
++              case 0:
++                      return (NFSTAT & 0x01);
++              case 1: /* RnB 3 */
++                      return ((val>>6) & 0x01);
++              case 2: /* RnB 4 */
++                      return ((val>>7) & 0x01);
++              case 3: /* RnB 2 */
++                      return  ((val>>5) & 0x01);
++              default:
++                      return 0;
++      }
++}
++
++/* 4G Nand flash chip select function */
++static void hxd8_nand_select_chip(struct nand_chip *this, int chip)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++      if (chip == 0)
++              gpio->GPGDAT &=  ~(1 << 1);
++      else
++              gpio->GPGDAT |=  (1 << 1);
++
++      if (chip == 1)
++              gpio->GPADAT &=  ~(1 << 15);
++      else
++              gpio->GPADAT |= (1 << 15);
++
++      if (chip == 2)
++              gpio->GPADAT &=  ~(1 << 16);
++      else
++              gpio->GPADAT |=  (1 << 16);
++
++      if (chip == 3)
++              gpio->GPADAT &=  ~(1 << 14);
++      else
++              gpio->GPADAT |= (1 << 14);
++
++      /* UGLY: ew don't have mtd_info pointer, but know that
++       * s3c24xx hwcontrol function does not use it for CLRNCE */
++      if (chip == -1)
++              this->hwcontrol(NULL, NAND_CTL_CLRNCE);
++      else
++              this->hwcontrol(NULL, NAND_CTL_SETNCE);
++}
++#endif
+ static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd)
+ {
+@@ -251,6 +304,11 @@
+       nand->eccmode = NAND_ECC_SOFT;
+ #endif
++#if defined(CONFIG_HXD8)
++      nand->dev_ready = hxd8_nand_dev_ready;
++      nand->select_chip = hxd8_nand_select_chip;
++#endif
++
+ #ifdef CONFIG_S3C2410_NAND_BBT
+       nand->options = NAND_USE_FLASH_BBT | NAND_DONT_CREATE_BBT;
+ #else
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-license.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-license.patch
new file mode 100644 (file)
index 0000000..227a97e
--- /dev/null
@@ -0,0 +1,712 @@
+Index: u-boot/common/Makefile
+===================================================================
+--- u-boot.orig/common/Makefile
++++ u-boot/common/Makefile
+@@ -34,7 +34,7 @@
+         cmd_dynenv.o cmd_eeprom.o cmd_elf.o cmd_ext2.o \
+         cmd_fat.o cmd_fdc.o cmd_fdt.o cmd_fdos.o cmd_flash.o cmd_fpga.o \
+         cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \
+-        cmd_load.o cmd_log.o \
++        cmd_license.o cmd_load.o cmd_log.o \
+         cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \
+         cmd_nand.o cmd_net.o cmd_nvedit.o \
+         cmd_pci.o cmd_pcmcia.o cmd_portio.o \
+Index: u-boot/common/cmd_license.c
+===================================================================
+--- /dev/null
++++ u-boot/common/cmd_license.c
+@@ -0,0 +1,57 @@
++/*
++ * (C) Copyright 2007 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * 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>
++
++#if (CONFIG_COMMANDS & CFG_CMD_LICENSE)
++
++#define LICENSE_MAX   20480
++#include <command.h>
++#include <malloc.h>
++#include <license.h>
++int gunzip(void *, int, unsigned char *, unsigned long *);
++
++int do_license(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++      char *tok, *dst = malloc(LICENSE_MAX);
++      unsigned long len = LICENSE_MAX;
++
++      if (!dst)
++              return -1;
++
++      if (gunzip(dst, LICENSE_MAX, gpl_gz, &len) != 0) {
++              printf("Error uncompressing license text\n");
++              free(dst);
++              return -1;
++      }
++      puts(dst);
++      free(dst);
++
++      return 0;
++}
++
++U_BOOT_CMD(license, 1, 1, do_license,
++         "license - print GPL license text\n",
++         NULL);
++
++#endif /* CFG_CMD_LICENSE */
+Index: u-boot/include/cmd_confdefs.h
+===================================================================
+--- u-boot.orig/include/cmd_confdefs.h
++++ u-boot/include/cmd_confdefs.h
+@@ -75,6 +75,7 @@
+ #define CFG_CMD_FPGA  0x0000010000000000ULL   /* FPGA configuration Support   */
+ #define CFG_CMD_HWFLOW        0x0000020000000000ULL   /* RTS/CTS hw flow control      */
+ #define CFG_CMD_SAVES 0x0000040000000000ULL   /* save S record dump           */
++#define CFG_CMD_LICENSE       0x0000080000000000ULL   /* Display GPL License          */
+ #define CFG_CMD_SPI   0x0000100000000000ULL   /* SPI utility                  */
+ #define CFG_CMD_FDOS  0x0000200000000000ULL   /* Floppy DOS support           */
+ #define CFG_CMD_VFD   0x0000400000000000ULL   /* VFD support (TRAB)           */
+Index: u-boot/include/license.h
+===================================================================
+--- /dev/null
++++ u-boot/include/license.h
+@@ -0,0 +1,584 @@
++/* bin2header converting 'gpl.gz' */
++unsigned char gpl_gz[] = {
++      0x1f, 0x8b, 0x08, 0x08, 0xb2, 0x10, 0x0d, 0x46, 0x00, 0x03,
++      0x67, 0x70, 0x6c, 0x00, 0x9d, 0x5b, 0x5d, 0x77, 0xdb, 0x46,
++      0x92, 0x7d, 0x4e, 0xff, 0x8a, 0x3e, 0x7e, 0x89, 0x74, 0x0e,
++      0xc3, 0xc4, 0x9e, 0x9d, 0xdd, 0x49, 0xfc, 0x44, 0x49, 0x94,
++      0xcd, 0x1d, 0x99, 0x52, 0x48, 0xca, 0x8e, 0x1f, 0x41, 0xb2,
++      0x29, 0x62, 0x0c, 0x02, 0x5c, 0x7c, 0x48, 0xe6, 0xbf, 0xdf,
++      0x7b, 0xab, 0xba, 0x81, 0x06, 0x49, 0x25, 0xb3, 0x9b, 0x93,
++      0xc4, 0x16, 0x09, 0x54, 0xd7, 0x77, 0xdd, 0xaa, 0x2e, 0xfd,
++      0xf0, 0x83, 0xc5, 0x3f, 0x1f, 0xa6, 0x8f, 0xf6, 0xc3, 0x78,
++      0x3a, 0x9e, 0x8d, 0xee, 0xec, 0xc3, 0xe3, 0xd5, 0xdd, 0xe4,
++      0xda, 0xe2, 0xbf, 0xf1, 0x74, 0x3e, 0x36, 0x3f, 0xc8, 0x03,
++      0xf8, 0xe7, 0xb3, 0x2b, 0xab, 0xb4, 0xc8, 0xed, 0xbb, 0x81,
++      0xfd, 0xef, 0x26, 0x77, 0xf6, 0xed, 0xaf, 0xbf, 0xbe, 0x35,
++      0xc6, 0x5e, 0x17, 0xfb, 0x43, 0x99, 0x3e, 0x6d, 0x6b, 0x7b,
++      0x71, 0x7d, 0x89, 0x0f, 0xff, 0xf1, 0xeb, 0x40, 0xbe, 0xb2,
++      0xb7, 0xa5, 0x73, 0x76, 0x5e, 0x6c, 0xea, 0x97, 0xa4, 0x74,
++      0xf6, 0xb6, 0x68, 0xf2, 0x75, 0x52, 0x83, 0xc0, 0xc0, 0x4e,
++      0xf2, 0xd5, 0x70, 0x60, 0xec, 0xdf, 0xf9, 0x4c, 0x92, 0x7f,
++      0xcb, 0xd2, 0xdc, 0xce, 0x6b, 0x3c, 0x5d, 0x0f, 0xec, 0x6d,
++      0xba, 0xa9, 0xb7, 0xf6, 0x36, 0x2b, 0x8a, 0x72, 0x60, 0xaf,
++      0x8a, 0xaa, 0xe6, 0xf3, 0x9f, 0x46, 0xf6, 0x97, 0x77, 0x6f,
++      0xdf, 0xfe, 0xf2, 0xd3, 0xdb, 0xbf, 0xfd, 0xf2, 0xd6, 0x3e,
++      0xce, 0x47, 0xc6, 0x8e, 0x9f, 0x5d, 0x79, 0x28, 0xc0, 0x45,
++      0x5a, 0xd9, 0xbd, 0x2b, 0x77, 0x69, 0x5d, 0xbb, 0xb5, 0xad,
++      0x0b, 0xbb, 0x02, 0x3b, 0x36, 0xc9, 0xd7, 0x76, 0x9d, 0x56,
++      0x75, 0x99, 0x2e, 0x9b, 0xda, 0x59, 0x3c, 0xbb, 0xc4, 0xd1,
++      0x3b, 0x7e, 0x99, 0xba, 0xca, 0xd8, 0x62, 0x63, 0xeb, 0x2d,
++      0xde, 0xcc, 0xd2, 0x95, 0xcb, 0x2b, 0x67, 0xd7, 0xc5, 0xaa,
++      0xd9, 0xb9, 0x1c, 0xe7, 0xe3, 0x79, 0xbb, 0xda, 0x26, 0xf9,
++      0x53, 0x9a, 0x3f, 0xd9, 0xb4, 0x26, 0xf9, 0xbc, 0xa8, 0x6d,
++      0x92, 0x65, 0xc5, 0x8b, 0x5b, 0x0f, 0x0d, 0xd4, 0x21, 0xfa,
++      0x78, 0x28, 0x5d, 0xb2, 0x5b, 0x66, 0x0e, 0x0a, 0xb0, 0x8b,
++      0xad, 0x0b, 0x94, 0x2a, 0xbb, 0x29, 0x4a, 0xbb, 0x03, 0xdf,
++      0xb6, 0x0a, 0x92, 0xf3, 0xbf, 0xb5, 0xab, 0xd2, 0xa7, 0x5c,
++      0x39, 0xac, 0x93, 0x6f, 0xf8, 0xf0, 0x25, 0x39, 0xd8, 0x43,
++      0xd1, 0x94, 0x66, 0x03, 0xc1, 0xd7, 0xc5, 0x8e, 0xdf, 0x54,
++      0x5b, 0x79, 0x1e, 0xcc, 0x0b, 0x0b, 0x10, 0xae, 0x1e, 0x5a,
++      0x7b, 0x75, 0x00, 0xdf, 0x79, 0x5d, 0x26, 0x15, 0xf8, 0xab,
++      0x71, 0x96, 0x18, 0xcb, 0xe5, 0xae, 0x4c, 0x32, 0xfb, 0xd0,
++      0x2c, 0x71, 0xb4, 0xb9, 0xf3, 0x82, 0x80, 0xdd, 0x34, 0xaf,
++      0x5d, 0xbe, 0xd6, 0xa3, 0x9e, 0x9a, 0x04, 0x0a, 0xae, 0x61,
++      0x07, 0x1e, 0x65, 0xff, 0xec, 0x28, 0x7e, 0x67, 0x02, 0xcf,
++      0x3f, 0xfd, 0x84, 0x47, 0x76, 0xe4, 0xb3, 0x6a, 0xf0, 0x18,
++      0x0f, 0x6d, 0xc5, 0xc1, 0x11, 0x7c, 0x56, 0x04, 0x85, 0x5a,
++      0xc0, 0x63, 0x65, 0x9b, 0x0a, 0xbe, 0x31, 0xa4, 0x26, 0xd2,
++      0xca, 0xf4, 0x59, 0xb3, 0x81, 0xb5, 0x64, 0xbf, 0xcf, 0xa0,
++      0x7c, 0x1e, 0x2e, 0xfa, 0x11, 0x1b, 0xb8, 0xbe, 0x97, 0x98,
++      0xce, 0x4b, 0x7e, 0xac, 0x22, 0x0d, 0xe6, 0x22, 0x4d, 0x92,
++      0x1f, 0x6c, 0x81, 0x77, 0x4a, 0xbb, 0x2f, 0x8b, 0xa7, 0x32,
++      0xd9, 0xd9, 0x97, 0x6d, 0x41, 0xca, 0x4d, 0xbd, 0x2d, 0xca,
++      0x0a, 0x5a, 0xda, 0xc1, 0x0f, 0xf0, 0xa4, 0x69, 0x2a, 0x35,
++      0x1f, 0x58, 0xba, 0x98, 0x17, 0x3b, 0xe7, 0x5f, 0x7b, 0xcd,
++      0x23, 0x7b, 0xc2, 0xad, 0x0a, 0xb8, 0x0b, 0xd4, 0xb7, 0x3c,
++      0x98, 0xa0, 0xec, 0x3b, 0x57, 0x41, 0x40, 0xfb, 0x8a, 0x60,
++      0x69, 0x5e, 0xd5, 0x2e, 0x59, 0x0f, 0x2f, 0xad, 0xfd, 0x5a,
++      0x34, 0x76, 0x95, 0xe4, 0x22, 0xeb, 0xc1, 0x2a, 0x2f, 0xa2,
++      0x79, 0xcf, 0x70, 0x05, 0x03, 0x16, 0xc5, 0x90, 0x4e, 0xf3,
++      0x65, 0xeb, 0x72, 0xfb, 0x02, 0xbd, 0xee, 0x5d, 0xf2, 0x8d,
++      0xca, 0x10, 0xa5, 0x06, 0x46, 0x06, 0xfc, 0x8a, 0x0c, 0x95,
++      0x6e, 0xe3, 0xca, 0x92, 0xd2, 0x40, 0x01, 0xde, 0x7e, 0x03,
++      0xba, 0xa4, 0xd9, 0x97, 0x38, 0x1f, 0x02, 0xde, 0x37, 0xaf,
++      0x71, 0x56, 0x9d, 0xb8, 0x5e, 0x6c, 0xd2, 0xa4, 0xa6, 0x53,
++      0x98, 0x6d, 0xf2, 0xac, 0x06, 0x8e, 0x9c, 0x23, 0x0a, 0x1d,
++      0x8d, 0x98, 0x13, 0xfe, 0xec, 0x85, 0x77, 0x9d, 0xf2, 0x49,
++      0x3c, 0xc1, 0x48, 0x38, 0x41, 0x49, 0xcf, 0x38, 0xda, 0xa6,
++      0x1b, 0x92, 0xb6, 0x2f, 0x69, 0xb5, 0xbd, 0x1c, 0xb4, 0x47,
++      0x41, 0x96, 0x95, 0x4b, 0x9f, 0x49, 0xa4, 0x29, 0x57, 0x24,
++      0xbd, 0x86, 0x61, 0x4a, 0x51, 0xd8, 0x93, 0x43, 0xa8, 0xd5,
++      0x26, 0xbc, 0x08, 0x9f, 0xc5, 0x8f, 0xd1, 0xab, 0x7c, 0xc6,
++      0x3b, 0x6a, 0xcf, 0x19, 0xf1, 0x3a, 0x7c, 0xcf, 0x82, 0xc7,
++      0x95, 0x72, 0x49, 0x22, 0xb9, 0xcd, 0xdd, 0x8b, 0xf2, 0x1b,
++      0xf4, 0xfe, 0x5e, 0x7d, 0x28, 0x90, 0xfb, 0x96, 0x17, 0x2f,
++      0x2d, 0xdd, 0x75, 0x41, 0x9a, 0x15, 0x29, 0x43, 0xcf, 0x95,
++      0x58, 0x67, 0x51, 0xf0, 0xd5, 0xda, 0xad, 0x6a, 0x8d, 0x1c,
++      0x49, 0x70, 0x95, 0x58, 0x25, 0x77, 0x91, 0x2e, 0x4b, 0x47,
++      0x4d, 0xad, 0xe8, 0x44, 0x95, 0x92, 0x87, 0x32, 0x96, 0xe9,
++      0xda, 0xc0, 0x57, 0x99, 0x9d, 0xa8, 0x4c, 0x97, 0x4b, 0xa4,
++      0xfb, 0x43, 0x94, 0x12, 0x19, 0xa7, 0x47, 0x57, 0xdf, 0xf4,
++      0xab, 0x82, 0x56, 0x29, 0x19, 0xb7, 0xa5, 0x08, 0xa8, 0x4f,
++      0x0d, 0xcd, 0x42, 0xdf, 0xe9, 0x9d, 0x82, 0x88, 0xae, 0xb2,
++      0xa4, 0x16, 0xe2, 0x2b, 0x57, 0xd6, 0x09, 0x04, 0xc6, 0x13,
++      0x7b, 0x7c, 0x99, 0x2e, 0xd3, 0x2c, 0xad, 0x53, 0x9f, 0x86,
++      0x48, 0x59, 0x35, 0x6a, 0xce, 0x5a, 0x34, 0xd6, 0xe4, 0x80,
++      0x1c, 0x79, 0xf5, 0xef, 0x8a, 0x75, 0xba, 0xa1, 0xfb, 0x8a,
++      0x2a, 0x6e, 0xf1, 0x85, 0xfb, 0x9e, 0xec, 0xf6, 0x19, 0x1e,
++      0xf2, 0x4f, 0x9c, 0x25, 0x57, 0x35, 0xab, 0xad, 0x4d, 0x82,
++      0xca, 0xa1, 0xab, 0xad, 0x63, 0xd4, 0x19, 0xfc, 0x54, 0xa7,
++      0x22, 0xb1, 0xa4, 0x0c, 0xbb, 0x71, 0x20, 0x24, 0xe7, 0x34,
++      0x48, 0x03, 0x4f, 0xa9, 0xf7, 0x3f, 0x78, 0x47, 0x0a, 0x52,
++      0x39, 0x94, 0xc3, 0xb4, 0xd2, 0x69, 0x41, 0xf4, 0xca, 0x30,
++      0xb2, 0xf4, 0xd5, 0xa1, 0x46, 0x99, 0xbc, 0x7b, 0xe4, 0xce,
++      0x78, 0xe5, 0x20, 0x01, 0x36, 0x68, 0x5d, 0x2d, 0x72, 0x2f,
++      0x7c, 0x6b, 0x22, 0xcf, 0x03, 0x9d, 0x11, 0x5c, 0xa2, 0xe5,
++      0xa3, 0xda, 0xc2, 0x25, 0xf0, 0xcc, 0x2e, 0x38, 0x03, 0x8a,
++      0x0a, 0x53, 0x90, 0x50, 0x55, 0x87, 0xc1, 0xdf, 0xd2, 0xd2,
++      0x04, 0xd3, 0x30, 0x86, 0xdd, 0x39, 0x2f, 0x81, 0xdf, 0xa3,
++      0x84, 0xd5, 0x2f, 0xb0, 0x69, 0xed, 0xf6, 0xd5, 0x6f, 0xf6,
++      0xe2, 0xed, 0xa5, 0x94, 0x25, 0xad, 0x92, 0x7d, 0xad, 0xc3,
++      0x2d, 0xcd, 0xc5, 0xbb, 0x4b, 0xe8, 0x0f, 0x71, 0xee, 0xdd,
++      0x24, 0x2a, 0x4c, 0x2f, 0xdb, 0x14, 0x4a, 0xa5, 0x8e, 0x2a,
++      0xf9, 0x32, 0x73, 0x4f, 0x08, 0x73, 0x29, 0x78, 0x95, 0x14,
++      0x63, 0x5f, 0xf1, 0x06, 0xb1, 0x85, 0x41, 0xf3, 0x67, 0xa9,
++      0x42, 0x62, 0xc6, 0xf8, 0x3c, 0xe1, 0x7a, 0x94, 0x55, 0xd0,
++      0x10, 0x6d, 0xe1, 0x12, 0x5a, 0x4c, 0xb2, 0x27, 0xd2, 0xad,
++      0x17, 0x85, 0x54, 0x19, 0x2c, 0x10, 0x48, 0x1d, 0x5e, 0xa2,
++      0x31, 0x38, 0xbc, 0x77, 0x38, 0x23, 0x0a, 0x77, 0xa1, 0x08,
++      0x37, 0x74, 0xdc, 0xaa, 0xc6, 0x6b, 0x55, 0x6b, 0x0a, 0xcd,
++      0xa6, 0x79, 0x81, 0xf7, 0x4b, 0x16, 0xa1, 0x83, 0x1c, 0x29,
++      0xd2, 0xf5, 0x6a, 0x0d, 0x0c, 0x31, 0xd9, 0x9c, 0x94, 0x18,
++      0x61, 0x3e, 0x95, 0x34, 0x8c, 0xcf, 0x77, 0x8e, 0xa7, 0xb8,
++      0xac, 0xd2, 0x5a, 0xb0, 0x4f, 0x90, 0x8f, 0xc1, 0x61, 0x4e,
++      0xfe, 0x8c, 0xcf, 0x16, 0x55, 0xec, 0x41, 0x60, 0xd7, 0x9b,
++      0x0c, 0xcc, 0xbc, 0x04, 0xe7, 0x10, 0x07, 0x0a, 0x25, 0x9d,
++      0x27, 0x16, 0x30, 0x49, 0x9a, 0x27, 0xd9, 0x00, 0x67, 0xa8,
++      0x48, 0xac, 0x31, 0x50, 0x04, 0x2a, 0xfb, 0x4e, 0x4a, 0x69,
++      0x59, 0xac, 0x9b, 0x95, 0xb2, 0x21, 0x35, 0x84, 0xd6, 0x85,
++      0x77, 0x92, 0x00, 0x52, 0x73, 0x46, 0xd3, 0xd3, 0x0a, 0x11,
++      0x2d, 0xe3, 0xcb, 0xd1, 0x8f, 0x78, 0x60, 0xdf, 0xd4, 0x52,
++      0x60, 0xd4, 0x5d, 0x6e, 0xf9, 0x75, 0x76, 0x18, 0xc8, 0x21,
++      0x71, 0x7a, 0x22, 0x4b, 0xf5, 0x16, 0x88, 0x02, 0x95, 0x1b,
++      0x67, 0xa1, 0xda, 0x53, 0x97, 0x35, 0x4a, 0x88, 0x48, 0xef,
++      0x6b, 0xe3, 0x9e, 0x5f, 0xd7, 0x2c, 0xb3, 0xf0, 0x3b, 0xe6,
++      0x56, 0xc9, 0x20, 0xcf, 0x45, 0xba, 0x96, 0xf3, 0xd7, 0xcc,
++      0x8e, 0xa5, 0x4a, 0x8c, 0xfa, 0x15, 0xdc, 0x81, 0x85, 0x11,
++      0xc1, 0x99, 0xa8, 0xd2, 0xdb, 0xc2, 0x49, 0x21, 0xd2, 0x7c,
++      0x9d, 0x3e, 0xa7, 0xeb, 0x86, 0x4c, 0xd9, 0x62, 0x29, 0x89,
++      0x44, 0x0f, 0x69, 0xe1, 0x0c, 0x22, 0x3e, 0xb7, 0x0e, 0xbe,
++      0xb9, 0x92, 0x68, 0x93, 0x3a, 0xb4, 0xed, 0xc8, 0xe0, 0x4f,
++      0x94, 0x21, 0x57, 0x27, 0xe5, 0x61, 0xe8, 0x93, 0x26, 0x7c,
++      0x82, 0xee, 0x02, 0x33, 0x8b, 0xf3, 0x88, 0xc6, 0x77, 0xc9,
++      0x9a, 0x58, 0xc6, 0xae, 0x32, 0x97, 0x78, 0x0e, 0xa1, 0x02,
++      0x2f, 0x90, 0x86, 0xdf, 0xb2, 0x85, 0x50, 0x6b, 0x75, 0x4d,
++      0xef, 0x5a, 0x3f, 0x7a, 0xb4, 0xc1, 0x2c, 0x8f, 0x8f, 0xa9,
++      0xf7, 0xf6, 0xb9, 0x44, 0x70, 0xd9, 0x30, 0x40, 0xb0, 0x3d,
++      0xed, 0xdf, 0x46, 0xae, 0xd4, 0xa7, 0x02, 0x12, 0x6a, 0xd6,
++      0x24, 0x4d, 0x06, 0x0a, 0x24, 0x18, 0x74, 0xe9, 0xcb, 0xfb,
++      0xba, 0x51, 0x6f, 0x5b, 0x29, 0x18, 0xd8, 0x14, 0x04, 0x7b,
++      0x02, 0xf5, 0xfe, 0x02, 0x1a, 0xe3, 0xdb, 0xc5, 0x78, 0xf6,
++      0x69, 0x6e, 0x47, 0xd3, 0x1b, 0x7b, 0x7d, 0x3f, 0xbd, 0x99,
++      0x2c, 0x26, 0xf7, 0xd3, 0xb9, 0xbd, 0xbd, 0x9f, 0xe1, 0xc7,
++      0x87, 0xaf, 0x93, 0xe9, 0x87, 0x81, 0xbd, 0x99, 0xcc, 0x17,
++      0xb3, 0xc9, 0xd5, 0x23, 0xbf, 0x92, 0x07, 0x3f, 0xdd, 0xdf,
++      0x4c, 0x6e, 0x27, 0xd7, 0x23, 0x7e, 0x40, 0xde, 0x7f, 0x19,
++      0x0a, 0x6e, 0x3a, 0x07, 0x94, 0xbc, 0x37, 0x8a, 0xae, 0x21,
++      0x80, 0xa2, 0x98, 0x97, 0xa2, 0xfc, 0xe6, 0x13, 0x03, 0x71,
++      0x21, 0xac, 0x56, 0x99, 0x84, 0x9a, 0x61, 0xe9, 0xdd, 0x67,
++      0x89, 0x77, 0x57, 0xfa, 0x44, 0x97, 0x75, 0xb6, 0x45, 0xc6,
++      0xda, 0x52, 0x25, 0x07, 0x0f, 0x6c, 0x77, 0xc0, 0x9f, 0x50,
++      0x7a, 0x97, 0x36, 0xd6, 0xa6, 0x69, 0xcb, 0x8f, 0xaa, 0x30,
++      0xa0, 0xe4, 0xf3, 0xe8, 0x62, 0xa8, 0x5a, 0x7f, 0xf3, 0xa0,
++      0xfc, 0xbd, 0x01, 0x76, 0x76, 0xd0, 0xdb, 0xc0, 0x08, 0x64,
++      0x69, 0xd9, 0x97, 0xaa, 0x10, 0xc9, 0x40, 0xee, 0x25, 0xed,
++      0xc1, 0x25, 0xdf, 0x88, 0x28, 0xcb, 0x44, 0x83, 0x59, 0x4e,
++      0x0e, 0xd4, 0xcc, 0xce, 0xa1, 0xcc, 0x59, 0x97, 0x8a, 0xc8,
++      0xd1, 0x37, 0xa4, 0x41, 0xba, 0x60, 0x35, 0x7d, 0x86, 0xc1,
++      0xe0, 0x5e, 0x42, 0x45, 0x99, 0xef, 0x04, 0xce, 0x92, 0x97,
++      0xdf, 0x34, 0xa4, 0x53, 0xe1, 0x05, 0x92, 0xe3, 0x58, 0x7d,
++      0xd6, 0xab, 0xcd, 0x7b, 0x73, 0x8f, 0xb2, 0xdd, 0x17, 0xa5,
++      0x78, 0x81, 0x60, 0x89, 0x81, 0xf1, 0x0c, 0xb4, 0x1d, 0x04,
++      0x25, 0x60, 0x7a, 0x8f, 0x3d, 0xa6, 0x0a, 0x19, 0xb7, 0x2d,
++      0xcd, 0x6b, 0xa6, 0x0e, 0xca, 0x2f, 0x16, 0x33, 0x19, 0x42,
++      0xb3, 0x49, 0x9e, 0xa8, 0xb2, 0x8b, 0x8f, 0x48, 0x8c, 0xc8,
++      0x03, 0x1b, 0xa8, 0x78, 0xd0, 0xbe, 0xc0, 0x03, 0x05, 0xba,
++      0xaf, 0xb2, 0x86, 0xd0, 0x9d, 0x47, 0x14, 0x0d, 0x5d, 0x1d,
++      0x80, 0xd6, 0x7f, 0x9d, 0x9b, 0x60, 0x19, 0xfb, 0x26, 0x3e,
++      0xfd, 0x0d, 0x81, 0xe7, 0x98, 0x99, 0xdc, 0x07, 0x86, 0x64,
++      0xb8, 0x64, 0xbd, 0x2e, 0x9d, 0x64, 0xc9, 0xa4, 0xb2, 0x6f,
++      0x50, 0x3a, 0xde, 0xc0, 0xa1, 0x47, 0xc8, 0xee, 0xcf, 0x8a,
++      0x0f, 0x0a, 0xaf, 0x57, 0xe2, 0xaa, 0xd7, 0xc2, 0xa2, 0x27,
++      0xa4, 0x60, 0x49, 0xe2, 0xce, 0x0e, 0x1f, 0xab, 0x77, 0x78,
++      0x77, 0x78, 0xaf, 0x19, 0x56, 0x40, 0x59, 0x53, 0x57, 0xa9,
++      0x44, 0x3c, 0x0a, 0x28, 0xa8, 0x07, 0x57, 0x49, 0x98, 0x2c,
++      0x37, 0xa6, 0x6c, 0xf2, 0x13, 0xd5, 0xfb, 0x9c, 0x1c, 0x80,
++      0x8e, 0x5b, 0x0f, 0x3c, 0x60, 0x13, 0x6a, 0x48, 0xa3, 0xc8,
++      0x02, 0xc5, 0x2e, 0x7e, 0xc5, 0x44, 0x50, 0xbd, 0xc8, 0x89,
++      0xb6, 0x37, 0x72, 0x20, 0x6d, 0x2b, 0x25, 0x40, 0xb2, 0x68,
++      0x5a, 0x4b, 0x41, 0xb4, 0x27, 0x8e, 0x66, 0xc2, 0xc9, 0x17,
++      0xc8, 0x82, 0x6e, 0x4f, 0xe4, 0x95, 0x4b, 0x4f, 0x82, 0x84,
++      0x45, 0xe6, 0x96, 0x0e, 0xf0, 0x5c, 0xf2, 0x16, 0xe4, 0x3c,
++      0xc3, 0xf1, 0xe5, 0xd0, 0x7c, 0x51, 0x7c, 0x63, 0x5b, 0x27,
++      0x2b, 0x1b, 0xa2, 0x6d, 0xd2, 0xaa, 0x78, 0x4a, 0x28, 0x3b,
++      0xad, 0x90, 0xeb, 0xc2, 0x69, 0x21, 0x78, 0x3b, 0x54, 0x0c,
++      0x93, 0x1c, 0xfe, 0x9d, 0x76, 0x35, 0x40, 0x35, 0x4f, 0xe6,
++      0xc7, 0x2a, 0x86, 0x31, 0x34, 0x6f, 0x8c, 0xad, 0x89, 0x9a,
++      0xd3, 0x5c, 0x22, 0x64, 0x87, 0x22, 0xd0, 0x00, 0x87, 0x21,
++      0xf8, 0x90, 0xe5, 0x5d, 0x07, 0x7f, 0x0d, 0x55, 0xb3, 0x4f,
++      0x57, 0x4d, 0xd1, 0x54, 0x99, 0x9e, 0x8e, 0x9c, 0x23, 0xa9,
++      0x1c, 0xbe, 0x8b, 0x4f, 0xf6, 0x0c, 0x74, 0xd4, 0x17, 0x08,
++      0x21, 0x10, 0xc1, 0x33, 0x19, 0x3f, 0x65, 0xba, 0x48, 0xf3,
++      0x99, 0xc7, 0x0b, 0xb1, 0xca, 0x92, 0x74, 0x07, 0xad, 0x80,
++      0xe9, 0x50, 0xf8, 0xdf, 0xdb, 0x6f, 0xce, 0xed, 0x19, 0x12,
++      0xf4, 0x00, 0x0f, 0xee, 0x8c, 0xbe, 0x56, 0x85, 0x82, 0x45,
++      0xf8, 0xc3, 0xe6, 0xb8, 0x97, 0x09, 0xb5, 0xef, 0xa3, 0xf0,
++      0xc9, 0xb2, 0x72, 0x39, 0x4e, 0x61, 0x29, 0x83, 0x6c, 0x2d,
++      0x69, 0xc3, 0x67, 0x04, 0x43, 0x76, 0xdd, 0x61, 0x84, 0x03,
++      0xfa, 0xaa, 0x83, 0x23, 0x88, 0x28, 0x21, 0xb1, 0xf9, 0x73,
++      0x4c, 0x92, 0x15, 0xb0, 0xae, 0xc2, 0xb6, 0xee, 0x69, 0x98,
++      0xaa, 0xb5, 0x92, 0x36, 0x3a, 0x82, 0x5d, 0x3d, 0x8c, 0x41,
++      0xaa, 0xdd, 0x1e, 0x2a, 0x04, 0x47, 0xe6, 0xfd, 0x5a, 0x83,
++      0x39, 0x74, 0x6b, 0x7a, 0x92, 0xe2, 0xbb, 0x83, 0xa7, 0x92,
++      0x78, 0x98, 0x58, 0xec, 0x7d, 0x86, 0xa1, 0xcc, 0x2d, 0x3a,
++      0x8a, 0xe0, 0x17, 0x6b, 0xee, 0xf7, 0xd0, 0x97, 0x07, 0xcc,
++      0x2c, 0x9e, 0xf3, 0xae, 0xf3, 0x1c, 0x0f, 0xef, 0x84, 0xa2,
++      0x4a, 0x55, 0x9e, 0x77, 0x98, 0x90, 0x31, 0x7d, 0x66, 0x33,
++      0x9a, 0xd9, 0xf0, 0x44, 0x23, 0x65, 0x71, 0xa7, 0xec, 0xbe,
++      0x9a, 0x8a, 0x07, 0xbe, 0x94, 0xaa, 0x9f, 0xc6, 0x38, 0x53,
++      0x52, 0x7b, 0x3f, 0x11, 0xfa, 0x04, 0x6f, 0xcf, 0x94, 0x92,
++      0xb9, 0x17, 0xee, 0xad, 0x49, 0x96, 0x88, 0xdb, 0x33, 0x7e,
++      0x09, 0xd7, 0x00, 0xde, 0xde, 0x39, 0xa7, 0x4e, 0xa2, 0x52,
++      0x54, 0x2e, 0x2a, 0xe3, 0xbf, 0x51, 0x07, 0xd6, 0x26, 0x97,
++      0x5d, 0x0f, 0xb0, 0x4a, 0x9a, 0x4a, 0x1b, 0x88, 0x16, 0x32,
++      0x6e, 0xd2, 0x4c, 0xcb, 0xe7, 0x0a, 0xba, 0x15, 0xc5, 0x42,
++      0x46, 0x86, 0xb7, 0x77, 0x39, 0xa1, 0x51, 0x31, 0xaf, 0x4a,
++      0x4c, 0x87, 0x16, 0x53, 0xf4, 0xad, 0x39, 0x47, 0x29, 0x84,
++      0x0c, 0xb4, 0x66, 0xb3, 0xe5, 0x1d, 0x4f, 0x9f, 0x1a, 0x2a,
++      0x1f, 0xcb, 0x13, 0x3e, 0xc4, 0x37, 0xa9, 0x80, 0x96, 0x6c,
++      0xa4, 0x2f, 0x28, 0xc7, 0x47, 0x96, 0xef, 0x6c, 0x91, 0xd3,
++      0x49, 0xe6, 0x05, 0xc5, 0x59, 0xbe, 0x15, 0xfc, 0x55, 0xd6,
++      0x6d, 0x59, 0x97, 0xcf, 0x2a, 0x2d, 0x75, 0x94, 0xeb, 0x28,
++      0x05, 0x7a, 0xc3, 0x0a, 0x0d, 0x79, 0x4f, 0x50, 0x77, 0xb1,
++      0x61, 0x0f, 0xd4, 0x03, 0x54, 0xc8, 0x11, 0x89, 0x3f, 0x25,
++      0xa1, 0x16, 0x82, 0x3f, 0xb3, 0x44, 0x49, 0x34, 0xa6, 0xe5,
++      0xba, 0xa5, 0x42, 0x07, 0x7a, 0x0d, 0x09, 0x84, 0xd2, 0xaf,
++      0xe2, 0xaf, 0x2e, 0x03, 0x72, 0x6f, 0x55, 0x1f, 0x0a, 0x7d,
++      0x0e, 0xbf, 0x12, 0x58, 0x09, 0x50, 0xbb, 0xd6, 0xc9, 0x8c,
++      0x34, 0x07, 0x1c, 0x4e, 0x95, 0x09, 0xcb, 0x10, 0xf2, 0x8c,
++      0x17, 0x1e, 0x89, 0x16, 0x09, 0x36, 0x6a, 0x09, 0x55, 0x95,
++      0xf4, 0x51, 0xf9, 0x12, 0x96, 0x2a, 0x59, 0x52, 0x43, 0x16,
++      0x66, 0x44, 0xd0, 0xf5, 0xe4, 0xf5, 0x88, 0xa0, 0x60, 0xc4,
++      0x34, 0xf7, 0x0c, 0x71, 0xc2, 0x54, 0xae, 0x51, 0x69, 0x4b,
++      0x66, 0x0b, 0xe9, 0x0b, 0xc1, 0x5d, 0xca, 0x24, 0x5f, 0xd2,
++      0x28, 0x00, 0x4a, 0x74, 0x68, 0xf5, 0xa7, 0x3c, 0x2f, 0x1a,
++      0x64, 0x17, 0x8e, 0x00, 0x7d, 0x11, 0x96, 0xa0, 0xe8, 0x65,
++      0x3c, 0x7b, 0x36, 0xe3, 0x25, 0x42, 0xc0, 0x7f, 0xf0, 0x7a,
++      0xeb, 0x73, 0x41, 0x48, 0x8b, 0xf6, 0x65, 0x10, 0x10, 0x58,
++      0xeb, 0x1f, 0x3e, 0x0a, 0x94, 0x8f, 0xf6, 0x85, 0xcb, 0x6e,
++      0x5e, 0x21, 0xb3, 0x35, 0x89, 0xf8, 0x08, 0xd5, 0xab, 0xc7,
++      0x07, 0x6d, 0x8b, 0xb9, 0x84, 0xc2, 0x71, 0xc0, 0xf8, 0x32,
++      0xea, 0xb2, 0x2c, 0xd4, 0x2f, 0x92, 0xb3, 0xd2, 0xeb, 0x16,
++      0xf6, 0x39, 0x75, 0x2f, 0x47, 0x39, 0x51, 0xa8, 0x74, 0x08,
++      0xef, 0x62, 0xfc, 0x7d, 0xe5, 0x24, 0x5d, 0xfd, 0xc6, 0x02,
++      0xdb, 0x2b, 0xd9, 0x75, 0xe5, 0xb2, 0x4d, 0x98, 0x38, 0x06,
++      0x1b, 0x80, 0x37, 0x21, 0xc1, 0x5a, 0x27, 0x25, 0xbd, 0xf5,
++      0x04, 0x55, 0xbe, 0x0e, 0x09, 0xf2, 0x9e, 0xca, 0x07, 0x9a,
++      0xc4, 0x7a, 0x19, 0x28, 0x48, 0x73, 0x8a, 0x10, 0xfe, 0xa7,
++      0x49, 0x4b, 0x9d, 0xc0, 0x28, 0xc5, 0x23, 0x62, 0xc3, 0x4b,
++      0xd3, 0x4e, 0x4d, 0xe4, 0xd1, 0x9d, 0x8e, 0x14, 0x64, 0x22,
++      0xe7, 0x8b, 0x49, 0xeb, 0xae, 0x72, 0x64, 0x17, 0x1d, 0xd2,
++      0x8a, 0x9a, 0x94, 0x50, 0x00, 0xdf, 0x27, 0x68, 0x02, 0x6d,
++      0xe5, 0xfc, 0xd8, 0x45, 0xf4, 0xc3, 0x66, 0x52, 0x5e, 0x51,
++      0x2c, 0xf4, 0x6a, 0x64, 0x0e, 0xa4, 0x2c, 0x71, 0xf2, 0xb0,
++      0x24, 0x1f, 0x49, 0x55, 0xe4, 0xa0, 0x26, 0x73, 0x5c, 0x22,
++      0xa3, 0x52, 0x00, 0x62, 0x07, 0x3b, 0xf8, 0x70, 0xe5, 0x10,
++      0x7c, 0x74, 0x33, 0x1e, 0x50, 0x79, 0xb8, 0xb7, 0x83, 0x8a,
++      0x9f, 0xd9, 0x85, 0xd5, 0x0c, 0x84, 0x38, 0x04, 0xd5, 0xb0,
++      0x04, 0x3c, 0x12, 0xa1, 0x03, 0x4e, 0xb1, 0x64, 0x50, 0xdd,
++      0xc9, 0x59, 0xa0, 0xb2, 0xb5, 0xec, 0x4b, 0x24, 0x1d, 0xe5,
++      0x23, 0x99, 0x76, 0x24, 0xd5, 0xd1, 0xd1, 0x9c, 0x38, 0x37,
++      0x75, 0xfb, 0x82, 0x39, 0xf2, 0xb9, 0x2a, 0xd9, 0x45, 0x5a,
++      0xc1, 0xdb, 0x92, 0x79, 0xa4, 0xc3, 0xd4, 0x0c, 0xa3, 0x9d,
++      0x49, 0x5a, 0xf5, 0x6a, 0x8a, 0x39, 0xae, 0x29, 0x92, 0x57,
++      0x63, 0xbc, 0xe9, 0x6b, 0x96, 0xd2, 0x08, 0x2d, 0xa1, 0x7f,
++      0x2b, 0x24, 0x21, 0xd3, 0xd7, 0x80, 0x4e, 0x7f, 0xbb, 0x61,
++      0x88, 0x76, 0x79, 0x8a, 0x01, 0x02, 0x16, 0x46, 0x0b, 0xf1,
++      0x9d, 0xf3, 0x70, 0x6f, 0x7a, 0x43, 0xd3, 0x96, 0xfe, 0x98,
++      0x80, 0x31, 0x1b, 0x29, 0x16, 0x3a, 0x0c, 0xc1, 0x07, 0xd2,
++      0x7a, 0xaa, 0x58, 0xa5, 0x7b, 0x4a, 0xca, 0x35, 0x6a, 0x81,
++      0xd8, 0x1f, 0x2f, 0xd9, 0x17, 0x56, 0x69, 0x1d, 0x8d, 0x2d,
++      0xf0, 0xe2, 0x20, 0xba, 0x23, 0x20, 0xa7, 0x32, 0x7c, 0xaf,
++      0xdb, 0x7c, 0xe9, 0xf5, 0x24, 0xb5, 0x88, 0xb8, 0x28, 0x9a,
++      0xfe, 0x09, 0x4e, 0xad, 0x6a, 0x13, 0x0f, 0x8e, 0xf0, 0x98,
++      0x36, 0x77, 0x25, 0xaf, 0x33, 0x00, 0x02, 0x84, 0x59, 0x1d,
++      0x03, 0xe0, 0xb9, 0xf7, 0x16, 0x56, 0xda, 0x4a, 0xdf, 0xd0,
++      0x1d, 0x25, 0xdd, 0x8d, 0x71, 0xdf, 0x5d, 0xa9, 0xcd, 0x6f,
++      0x18, 0x9b, 0xe9, 0x64, 0x88, 0x03, 0x8c, 0xec, 0xac, 0xb2,
++      0xa3, 0xfe, 0xa9, 0x28, 0x81, 0xe6, 0x32, 0xce, 0x32, 0x42,
++      0x37, 0x55, 0x9d, 0x45, 0x02, 0x90, 0x79, 0x92, 0xb3, 0xb3,
++      0x48, 0xf5, 0x1a, 0x67, 0xc7, 0x44, 0x97, 0x3c, 0x3d, 0x51,
++      0x4b, 0x81, 0xac, 0x6f, 0x79, 0x54, 0x0e, 0x6a, 0xe5, 0x1c,
++      0x21, 0x73, 0x0c, 0xb5, 0x24, 0x3f, 0xca, 0x87, 0x7f, 0x02,
++      0x44, 0x2e, 0xf9, 0x73, 0x62, 0x9f, 0x8b, 0xac, 0xe1, 0x44,
++      0x7f, 0x83, 0xa6, 0xb7, 0xaa, 0x8b, 0x12, 0x7d, 0x95, 0x4f,
++      0xe9, 0x9d, 0x7c, 0x0a, 0x7d, 0xbb, 0x24, 0xb4, 0x2c, 0x43,
++      0xfa, 0x8b, 0xb8, 0xd3, 0xac, 0x29, 0x3e, 0xcd, 0x26, 0xe5,
++      0x6c, 0x91, 0xfb, 0xdb, 0x9f, 0x23, 0xf5, 0x63, 0x11, 0x8e,
++      0xb9, 0x67, 0x07, 0xa9, 0xb5, 0x34, 0xa0, 0x9f, 0x77, 0x97,
++      0x2c, 0x51, 0xc5, 0xf2, 0x5f, 0x9c, 0xa8, 0x84, 0x09, 0x38,
++      0xac, 0xb7, 0x6a, 0x6a, 0xc9, 0x37, 0x04, 0x64, 0x67, 0xca,
++      0xaf, 0x99, 0x87, 0x88, 0x7b, 0x2b, 0x3c, 0xbc, 0xb3, 0x02,
++      0xa2, 0x5e, 0xc3, 0x50, 0x48, 0x06, 0x1c, 0x98, 0xf9, 0x98,
++      0xd2, 0x81, 0x06, 0x34, 0xd0, 0xc1, 0xa7, 0xd1, 0x0a, 0x25,
++      0x79, 0x4f, 0xb4, 0x02, 0xff, 0x6d, 0xad, 0xc1, 0xcf, 0x32,
++      0x27, 0xa5, 0xae, 0xd4, 0x89, 0xb2, 0xd4, 0xc1, 0x1d, 0x22,
++      0x03, 0x00, 0xea, 0x27, 0xd6, 0x72, 0x32, 0xa9, 0xf8, 0xa9,
++      0xeb, 0x41, 0x06, 0x3e, 0xe6, 0x43, 0xd4, 0x46, 0x33, 0x85,
++      0x3f, 0x01, 0x82, 0x5a, 0x6a, 0xfa, 0xe2, 0x88, 0x81, 0xbd,
++      0xf1, 0x56, 0xa0, 0x56, 0xec, 0x92, 0x32, 0x85, 0xff, 0x37,
++      0x61, 0x2c, 0xd4, 0x8d, 0x08, 0x59, 0x73, 0x14, 0x8c, 0xbd,
++      0x87, 0x0a, 0x07, 0x2d, 0x20, 0x3b, 0x95, 0x2c, 0x69, 0xe3,
++      0x49, 0x10, 0xf7, 0xc0, 0x3e, 0x27, 0x59, 0xaa, 0xe4, 0xa0,
++      0xb3, 0x0c, 0xd9, 0xb9, 0x96, 0xe9, 0x9b, 0xca, 0x75, 0x70,
++      0x49, 0x29, 0xd7, 0x34, 0x5d, 0x57, 0x21, 0xf8, 0x48, 0x12,
++      0xc2, 0x61, 0xe0, 0xf1, 0xb8, 0x07, 0x50, 0x39, 0xef, 0xb2,
++      0x74, 0xfc, 0x9c, 0xeb, 0x6d, 0x9e, 0xe0, 0x22, 0x7f, 0xbd,
++      0x15, 0x1a, 0x04, 0x16, 0x3f, 0x57, 0x06, 0xa8, 0xed, 0x15,
++      0x17, 0xfb, 0xeb, 0x40, 0x8a, 0xb0, 0xea, 0x5e, 0x28, 0x1c,
++      0x6b, 0x3c, 0x2a, 0xd1, 0xc7, 0xc6, 0xe9, 0xd9, 0x41, 0x70,
++      0x9f, 0xd6, 0xdf, 0x7f, 0xcf, 0x06, 0xaf, 0xeb, 0x5f, 0x25,
++      0xf9, 0x7f, 0xd8, 0x60, 0xf5, 0x9a, 0x77, 0xa5, 0x39, 0x55,
++      0xa0, 0x99, 0x22, 0x6a, 0x59, 0x05, 0x9e, 0xfa, 0xc2, 0x2c,
++      0x06, 0xd2, 0xd2, 0x7f, 0x74, 0x0b, 0xf5, 0x8a, 0xc8, 0x84,
++      0x28, 0x32, 0x3c, 0x4b, 0x32, 0xf0, 0x92, 0x6b, 0x3e, 0xf3,
++      0x28, 0xc6, 0xdf, 0xd9, 0xea, 0x74, 0x60, 0x23, 0xc3, 0xc3,
++      0x9c, 0x40, 0x94, 0x99, 0x12, 0x5d, 0xdb, 0xc9, 0xb4, 0x23,
++      0x4c, 0x11, 0x58, 0xf4, 0xf8, 0x7e, 0xcb, 0x5f, 0x0c, 0xb5,
++      0xfe, 0x3a, 0x78, 0x45, 0xde, 0x16, 0x9f, 0x26, 0xad, 0xd7,
++      0xb1, 0x2b, 0x87, 0x5e, 0x4a, 0x9d, 0xee, 0xd8, 0x79, 0xb3,
++      0x0c, 0xd5, 0x61, 0xa9, 0xda, 0xf7, 0xc8, 0xa5, 0x77, 0x3d,
++      0xb6, 0xe9, 0x92, 0x8a, 0x0e, 0xc4, 0x94, 0x17, 0xb9, 0x14,
++      0x54, 0x73, 0xec, 0xda, 0xca, 0xc9, 0x87, 0x78, 0x15, 0xe7,
++      0xe7, 0xb4, 0xfd, 0xc6, 0x0c, 0xfa, 0x94, 0xeb, 0xd0, 0x5b,
++      0xe9, 0x19, 0x62, 0xa6, 0x75, 0x20, 0xd7, 0x86, 0xbe, 0x9e,
++      0x6e, 0xe4, 0x74, 0x3d, 0x32, 0xdc, 0xc6, 0x9c, 0xf0, 0x85,
++      0xcf, 0x71, 0x48, 0xc3, 0x56, 0x29, 0xed, 0x9a, 0x16, 0x34,
++      0x76, 0x59, 0x53, 0x49, 0x63, 0x92, 0x54, 0x55, 0xb1, 0x4a,
++      0xc3, 0x3c, 0x0c, 0x21, 0x90, 0xd0, 0xf1, 0xdd, 0x26, 0xcd,
++      0x53, 0x9d, 0xb4, 0xb2, 0xcd, 0xf2, 0xcf, 0x6b, 0x1e, 0x2e,
++      0xd3, 0xbd, 0x5e, 0x27, 0xb3, 0x60, 0x9b, 0x50, 0xbf, 0xc8,
++      0x5c, 0xea, 0xc7, 0x64, 0x02, 0x7b, 0x38, 0x1f, 0xcf, 0xb2,
++      0x24, 0x06, 0x0e, 0x9d, 0x44, 0x90, 0xf2, 0x23, 0x0c, 0xff,
++      0x4c, 0xa5, 0x13, 0xdb, 0x99, 0x6a, 0xef, 0xc4, 0xe2, 0x2e,
++      0x60, 0xd9, 0xc1, 0x89, 0x3c, 0x71, 0xb8, 0xc8, 0x05, 0x1f,
++      0xab, 0x86, 0x1f, 0xc7, 0xf1, 0x2e, 0x4f, 0xae, 0x06, 0xdb,
++      0x49, 0x4f, 0x8b, 0x69, 0xe3, 0xd7, 0x2e, 0xd8, 0xb5, 0xeb,
++      0xb4, 0xd0, 0x53, 0x86, 0x8e, 0x96, 0xd2, 0x80, 0x18, 0xda,
++      0xe9, 0xb2, 0x8b, 0x84, 0x5d, 0xf2, 0x2f, 0x41, 0x00, 0x3b,
++      0x78, 0xb4, 0xa0, 0xd3, 0x0b, 0x95, 0x90, 0x1c, 0x7f, 0x83,
++      0x1b, 0xbb, 0x4c, 0xa1, 0x49, 0xc5, 0x34, 0x7e, 0xe9, 0x25,
++      0x34, 0xa8, 0x51, 0xa5, 0xf6, 0xac, 0xd5, 0xa1, 0xaa, 0x01,
++      0xdd, 0x64, 0xc6, 0xc4, 0xc4, 0xdb, 0x97, 0x9f, 0x8d, 0x12,
++      0xb4, 0xda, 0xe4, 0x82, 0x5b, 0x84, 0xe7, 0xf6, 0x28, 0xe3,
++      0x51, 0x7b, 0xe2, 0x23, 0x54, 0xe6, 0xcc, 0x7d, 0xed, 0xa1,
++      0xc8, 0x6f, 0x4e, 0xd0, 0x42, 0x44, 0x9d, 0x10, 0x2b, 0x8a,
++      0x00, 0xde, 0xd5, 0xf8, 0x31, 0x99, 0x38, 0x3a, 0xf8, 0x33,
++      0xa0, 0x2e, 0x47, 0xfb, 0x6d, 0x0c, 0x41, 0xc7, 0x89, 0xbf,
++      0x88, 0x16, 0x6f, 0x90, 0x29, 0xb5, 0x47, 0xb5, 0xe1, 0x2d,
++      0x4b, 0xb8, 0x8e, 0xd4, 0x4c, 0x2e, 0x8f, 0x08, 0x9c, 0x78,
++      0x5f, 0x80, 0xdb, 0x02, 0x46, 0x85, 0x18, 0xbe, 0x68, 0x04,
++      0xe7, 0x57, 0xe6, 0x1c, 0xac, 0xec, 0x65, 0x49, 0x5e, 0x51,
++      0x10, 0x1f, 0x37, 0x4f, 0xdb, 0x28, 0xb7, 0xa7, 0xfe, 0xbe,
++      0x5c, 0x67, 0x9c, 0xbb, 0x3d, 0x7a, 0xa6, 0x68, 0xa3, 0x24,
++      0x22, 0x72, 0x34, 0x2d, 0x8a, 0x94, 0x21, 0x90, 0xe1, 0x3f,
++      0x3a, 0xc8, 0x40, 0x27, 0xd2, 0x31, 0x90, 0x0e, 0x6b, 0xd0,
++      0xfd, 0xc9, 0x08, 0x5d, 0xe1, 0x6b, 0x0c, 0x5a, 0x7a, 0x50,
++      0xc2, 0xa8, 0xa3, 0xd2, 0x79, 0xdd, 0xf7, 0x3d, 0xc7, 0xb8,
++      0xd2, 0x3e, 0xf9, 0x4a, 0x1f, 0xb2, 0x79, 0x84, 0x54, 0x78,
++      0x95, 0xc9, 0xf1, 0x12, 0x9c, 0x62, 0x5f, 0x1b, 0x81, 0x38,
++      0x2f, 0x02, 0x06, 0x8b, 0x57, 0x8f, 0x7f, 0xfd, 0x74, 0xa6,
++      0x4f, 0x5e, 0x2a, 0xa9, 0x0b, 0xca, 0x45, 0x51, 0xd2, 0xb0,
++      0x0a, 0xd4, 0xbe, 0x96, 0xb1, 0x88, 0xa4, 0xb4, 0x63, 0xef,
++      0xd2, 0xf3, 0x0c, 0x5b, 0xa6, 0x0d, 0xc3, 0xa0, 0x5f, 0x22,
++      0x68, 0xb9, 0x11, 0x6a, 0x73, 0xab, 0x4e, 0xac, 0x44, 0x19,
++      0xe1, 0x8e, 0x5d, 0xac, 0xcb, 0x02, 0x11, 0x00, 0x5a, 0x34,
++      0x11, 0x6c, 0x2f, 0xdf, 0xc2, 0xda, 0x42, 0x5a, 0x76, 0xab,
++      0x37, 0x2d, 0x63, 0x12, 0x39, 0x62, 0x25, 0x76, 0x37, 0x4c,
++      0xc5, 0x81, 0x01, 0xb4, 0x83, 0xbc, 0xe5, 0xc2, 0xbf, 0x9b,
++      0x26, 0xd3, 0xc4, 0x92, 0xa5, 0x09, 0x5a, 0x47, 0x31, 0xdd,
++      0xdf, 0xd5, 0x74, 0xa1, 0xbb, 0x8b, 0x7b, 0x4d, 0x7a, 0xe4,
++      0xbe, 0x3e, 0x6a, 0xc1, 0xaa, 0x94, 0x23, 0xc9, 0x70, 0x33,
++      0x2d, 0x9e, 0xe3, 0x77, 0x2d, 0x24, 0xd7, 0xb6, 0xe2, 0x13,
++      0x13, 0x8b, 0x87, 0xf3, 0x02, 0xf3, 0x89, 0x0d, 0xbe, 0x0e,
++      0x6d, 0xfb, 0xf7, 0xb8, 0x7e, 0xa0, 0x87, 0x0c, 0xfe, 0x8a,
++      0x61, 0x38, 0x0d, 0xaa, 0xab, 0xe3, 0x9b, 0x0f, 0xdd, 0xbb,
++      0x61, 0xc3, 0x9b, 0x84, 0xa6, 0xac, 0x94, 0x1b, 0xba, 0x6d,
++      0xba, 0x4c, 0x6b, 0x1d, 0xd4, 0x67, 0xc9, 0x4b, 0x7b, 0x75,
++      0xef, 0xfb, 0xc4, 0x53, 0x79, 0x94, 0x0e, 0x6a, 0x4b, 0xc1,
++      0x8b, 0xe9, 0xe5, 0x41, 0x6f, 0xc5, 0x64, 0x5a, 0xd1, 0xc3,
++      0xd7, 0x47, 0xa3, 0xfb, 0x0b, 0x3f, 0x5e, 0x7c, 0x75, 0xc4,
++      0x7e, 0xa9, 0xa3, 0x1d, 0xde, 0x36, 0xae, 0x5a, 0xaf, 0xd1,
++      0xf3, 0x13, 0x3f, 0xd2, 0xed, 0xd9, 0xb8, 0x16, 0xfc, 0xca,
++      0x3b, 0x6a, 0xce, 0x1b, 0xc3, 0x8a, 0xd1, 0xff, 0xe5, 0x56,
++      0x4f, 0x39, 0x6e, 0xd9, 0x37, 0x47, 0x4a, 0x3c, 0xea, 0x70,
++      0xfc, 0x9e, 0xc3, 0x7f, 0x0e, 0xf5, 0x16, 0xa5, 0x4e, 0x77,
++      0xce, 0xe3, 0x93, 0x3f, 0x43, 0xfa, 0x7f, 0x21, 0x71, 0x1d,
++      0x6f, 0x34, 0x1c, 0x05, 0x90, 0x77, 0x7e, 0x76, 0xc8, 0x21,
++      0x1a, 0x43, 0x46, 0x33, 0xe1, 0x16, 0xd9, 0x7f, 0xa3, 0x6b,
++      0x22, 0x1a, 0xc4, 0xfd, 0x49, 0x62, 0x74, 0xbb, 0x1f, 0xf8,
++      0x42, 0x74, 0x4b, 0x2a, 0xaa, 0x79, 0x97, 0xed, 0x5e, 0xb9,
++      0x09, 0x0d, 0xfb, 0x13, 0x3e, 0x3d, 0xa5, 0x28, 0x0c, 0x7e,
++      0x6e, 0xb9, 0x69, 0x4a, 0xb9, 0xad, 0xea, 0x6d, 0x9b, 0xf8,
++      0x16, 0xac, 0x1b, 0xa9, 0xff, 0x68, 0xdb, 0x5e, 0xd3, 0xe7,
++      0x56, 0x9f, 0x00, 0xc4, 0xaf, 0xa1, 0x8a, 0xad, 0x5c, 0x70,
++      0x0d, 0x4d, 0x3f, 0x92, 0xfc, 0x7a, 0x8a, 0x82, 0x24, 0x34,
++      0xb6, 0xf8, 0xff, 0x8a, 0x76, 0xea, 0x22, 0xd0, 0x5f, 0x28,
++      0x45, 0xd9, 0x58, 0xe4, 0x38, 0x6a, 0xc8, 0xfe, 0x6b, 0x68,
++      0x27, 0x1b, 0xad, 0xeb, 0x32, 0x4d, 0x41, 0x88, 0xb6, 0xf7,
++      0x02, 0xac, 0x01, 0x68, 0xda, 0xff, 0xd5, 0xac, 0x9f, 0x64,
++      0x92, 0xa7, 0x18, 0x25, 0x6a, 0x4e, 0xf5, 0xc2, 0xd9, 0x00,
++      0x88, 0xb2, 0xe0, 0xb8, 0xf0, 0xd0, 0xc6, 0xdb, 0x33, 0xdc,
++      0x1e, 0x70, 0x5c, 0x63, 0x2f, 0xf4, 0xaa, 0x79, 0x97, 0xfa,
++      0xbd, 0x42, 0x7f, 0x59, 0x8d, 0x70, 0x6d, 0x5c, 0x75, 0x39,
++      0x30, 0x91, 0x17, 0x0a, 0x16, 0x16, 0x3d, 0x8a, 0x23, 0xd0,
++      0x77, 0x2e, 0xfc, 0xf2, 0x0b, 0x85, 0x52, 0xae, 0x00, 0xfc,
++      0x04, 0x90, 0xa0, 0x5b, 0x0e, 0x07, 0x77, 0x99, 0xfa, 0x32,
++      0x94, 0x69, 0xae, 0xf9, 0x21, 0x4c, 0x6a, 0x0f, 0xf4, 0xdb,
++      0x23, 0x8e, 0x62, 0x64, 0xa0, 0x97, 0x6d, 0x1a, 0xcb, 0x2c,
++      0x17, 0x1c, 0x7d, 0xf2, 0xdc, 0xb6, 0x32, 0xbe, 0xfe, 0xae,
++      0xee, 0x5b, 0xf8, 0xe5, 0x27, 0xbe, 0x1e, 0x4f, 0xf4, 0x0b,
++      0x0f, 0xc6, 0x2b, 0xae, 0xec, 0xc0, 0xbd, 0xaa, 0x74, 0xd7,
++      0x64, 0x08, 0x53, 0xa7, 0x57, 0x45, 0x7a, 0x7d, 0x81, 0x1a,
++      0xf2, 0xe4, 0x61, 0x65, 0x97, 0xf5, 0x4d, 0x7c, 0x69, 0x13,
++      0x6d, 0xea, 0x39, 0xd8, 0x52, 0x86, 0xef, 0xd1, 0x6b, 0xbe,
++      0xf2, 0x9f, 0x18, 0x91, 0xc8, 0x3b, 0x38, 0xe6, 0x2b, 0xb1,
++      0xe7, 0xef, 0xfc, 0x4f, 0xd7, 0x92, 0x92, 0x60, 0xdd, 0x76,
++      0x75, 0xa6, 0x68, 0x32, 0xc5, 0x71, 0xba, 0x1f, 0x6a, 0xcb,
++      0xe2, 0x80, 0x2e, 0xe1, 0xf0, 0x93, 0xec, 0x13, 0x44, 0xc1,
++      0x1d, 0xc1, 0x84, 0x70, 0x0a, 0x92, 0x9f, 0xa2, 0xde, 0x42,
++      0x76, 0x70, 0x8a, 0xf6, 0x7a, 0xcd, 0x5f, 0xb0, 0xac, 0x51,
++      0x16, 0x56, 0xdc, 0xcf, 0x90, 0xa1, 0x7d, 0xfb, 0x13, 0xba,
++      0x48, 0x01, 0x15, 0x90, 0x43, 0x45, 0x94, 0xcc, 0x23, 0x7d,
++      0x85, 0x5f, 0xf7, 0xa4, 0x33, 0x80, 0xab, 0xa0, 0xde, 0x25,
++      0x94, 0x44, 0xec, 0xac, 0x73, 0xa8, 0xb8, 0xce, 0xc9, 0x63,
++      0x4b, 0x26, 0x43, 0xde, 0xa7, 0x97, 0x2c, 0x5a, 0xed, 0x34,
++      0x48, 0x8c, 0xfc, 0x27, 0xec, 0x2b, 0x84, 0x8b, 0xae, 0x7c,
++      0x4e, 0xe6, 0x51, 0xf8, 0xeb, 0xd6, 0x65, 0x04, 0xd2, 0xda,
++      0x0b, 0x73, 0x8d, 0x2e, 0xd7, 0xa0, 0x74, 0x02, 0xf2, 0xb4,
++      0xf4, 0x0a, 0x09, 0x06, 0xe3, 0xaa, 0xc9, 0x12, 0x64, 0xda,
++      0xb4, 0x5c, 0x35, 0xbb, 0x4a, 0xb2, 0xb6, 0x66, 0xb8, 0x65,
++      0x92, 0x75, 0x29, 0xdc, 0xc5, 0xe4, 0xa3, 0x2d, 0x54, 0xa3,
++      0x33, 0xc9, 0x70, 0x9b, 0x12, 0x1e, 0x8a, 0x2e, 0x25, 0x8e,
++      0xb6, 0x56, 0xfd, 0xf6, 0x64, 0xae, 0x2e, 0x64, 0xe2, 0x63,
++      0x79, 0x7f, 0x3a, 0xe9, 0x4d, 0xdc, 0xf6, 0x4d, 0x29, 0x19,
++      0xec, 0xcc, 0xc8, 0x0d, 0x96, 0x69, 0x7c, 0x7d, 0x96, 0x9f,
++      0x34, 0xea, 0xa3, 0xd5, 0x93, 0xaa, 0x5b, 0xaa, 0xe0, 0x98,
++      0x1f, 0xae, 0x7a, 0xf0, 0xc3, 0x33, 0x99, 0xd6, 0x85, 0x2d,
++      0x3d, 0x3f, 0xaa, 0xd3, 0xb9, 0x41, 0x5a, 0x1f, 0xfc, 0x5d,
++      0x90, 0x91, 0x59, 0xb6, 0x3e, 0xf9, 0xbe, 0x7f, 0xf8, 0x36,
++      0xf1, 0x0d, 0x0d, 0xa5, 0x8b, 0x38, 0x0c, 0x77, 0x7c, 0x7e,
++      0x8d, 0x86, 0x42, 0x3f, 0x95, 0x9e, 0x62, 0xed, 0x77, 0x30,
++      0xbb, 0xfe, 0xba, 0x67, 0x62, 0xc5, 0xfc, 0x83, 0x76, 0xbc,
++      0x6a, 0x52, 0xba, 0x3e, 0x33, 0x89, 0x96, 0xf8, 0xbd, 0x2e,
++      0x67, 0x04, 0xef, 0xdf, 0xcb, 0x40, 0x9e, 0x0a, 0xb3, 0xf6,
++      0x93, 0xd8, 0xd1, 0x15, 0x78, 0xbe, 0xdb, 0xc7, 0x31, 0x4f,
++      0xdc, 0xea, 0x40, 0x58, 0x6b, 0xd6, 0xf1, 0xc7, 0xb4, 0x9d,
++      0xf8, 0x0b, 0x2f, 0xf0, 0x4b, 0xb9, 0x81, 0xe4, 0x6a, 0xdf,
++      0x09, 0x4b, 0x6e, 0x6d, 0x82, 0xb7, 0x4b, 0xea, 0xf2, 0x2d,
++      0x89, 0xac, 0x22, 0xfa, 0x7c, 0x5e, 0xe4, 0x3a, 0xef, 0xae,
++      0x24, 0x71, 0xca, 0x56, 0xcb, 0x2a, 0x6a, 0xd9, 0x12, 0x80,
++      0x25, 0x79, 0xe9, 0xbd, 0x9f, 0xa1, 0x36, 0xfb, 0xf6, 0xb2,
++      0x57, 0x36, 0xa8, 0x7e, 0x5e, 0x17, 0xb9, 0x1a, 0x60, 0x8d,
++      0xea, 0xb3, 0x96, 0xb5, 0x52, 0xd9, 0xb3, 0xb2, 0xd5, 0x56,
++      0x7c, 0x86, 0x60, 0x50, 0xca, 0x7b, 0x6f, 0x56, 0xd0, 0xf2,
++      0x1a, 0xf8, 0xeb, 0x92, 0x91, 0x67, 0x52, 0x97, 0x4f, 0xda,
++      0x6d, 0x09, 0x9f, 0x06, 0x7d, 0x25, 0xd4, 0x44, 0xbc, 0x2d,
++      0x52, 0xc1, 0x84, 0x8b, 0xa3, 0xa8, 0x89, 0xdd, 0x54, 0xf6,
++      0xe1, 0xc8, 0x28, 0x4f, 0xe1, 0x70, 0x5f, 0xb6, 0x9b, 0x5e,
++      0x7c, 0x8f, 0xb8, 0x84, 0x1a, 0xdc, 0xb3, 0x06, 0xc0, 0xd2,
++      0x9d, 0x56, 0x2b, 0xad, 0xaa, 0x55, 0x7d, 0x92, 0x9e, 0x59,
++      0xe5, 0xfe, 0x31, 0x0c, 0x37, 0x6b, 0xc7, 0x53, 0x8a, 0x9f,
++      0xfd, 0xc6, 0xeb, 0x51, 0xc2, 0x4a, 0xab, 0x68, 0x77, 0x82,
++      0x97, 0x07, 0x61, 0x31, 0x54, 0xda, 0xa2, 0x92, 0x39, 0xcb,
++      0xf7, 0xa6, 0x74, 0x95, 0xce, 0xf9, 0x97, 0x87, 0xee, 0x5a,
++      0x2b, 0xee, 0xd2, 0x35, 0x45, 0x77, 0x68, 0xe4, 0x64, 0x91,
++      0x88, 0x49, 0x51, 0x1a, 0xaf, 0xaa, 0xc7, 0xc7, 0x69, 0x17,
++      0x20, 0x09, 0x3d, 0x59, 0xaf, 0x75, 0xea, 0x40, 0x1f, 0x80,
++      0xb5, 0x9f, 0x1c, 0x1f, 0xdf, 0x6f, 0xe5, 0xfa, 0xbc, 0x27,
++      0x62, 0xb4, 0xf1, 0x82, 0xb2, 0xa6, 0x17, 0x71, 0x46, 0xf3,
++      0x70, 0x2b, 0xca, 0x40, 0xd7, 0x32, 0x93, 0xba, 0xff, 0x6a,
++      0xef, 0x37, 0x01, 0x74, 0x98, 0x93, 0x0b, 0x06, 0xd8, 0xa1,
++      0x13, 0x30, 0x9d, 0x22, 0x34, 0x73, 0x34, 0x95, 0x3f, 0xc0,
++      0xad, 0x59, 0x11, 0x73, 0xbd, 0x99, 0x5a, 0x25, 0x5a, 0x5c,
++      0xa3, 0x54, 0x0c, 0x8c, 0x5f, 0x20, 0x80, 0x79, 0x41, 0x52,
++      0x49, 0x3e, 0x8f, 0x58, 0x44, 0x98, 0xc3, 0x29, 0xc3, 0x78,
++      0xd1, 0xdf, 0x3d, 0x2e, 0x8b, 0xf5, 0xc9, 0x8a, 0x81, 0x58,
++      0xf5, 0xd7, 0xa1, 0xac, 0xc1, 0xbc, 0xba, 0x85, 0x4e, 0x4d,
++      0x85, 0xd5, 0x8b, 0xd2, 0x3d, 0xa7, 0x72, 0x75, 0xab, 0x26,
++      0xe7, 0x42, 0xf3, 0xb3, 0xfe, 0xfe, 0x45, 0x65, 0xbc, 0xed,
++      0x5f, 0x59, 0x47, 0x57, 0x08, 0x40, 0x10, 0xcb, 0x68, 0xc2,
++      0x9f, 0x10, 0x6f, 0x4e, 0xd9, 0x62, 0x1a, 0x12, 0x3b, 0xf4,
++      0x4b, 0x14, 0xf8, 0x94, 0xb9, 0x1d, 0xbc, 0x57, 0xfb, 0xb4,
++      0x94, 0x95, 0xf5, 0x30, 0x64, 0xaa, 0x18, 0xb7, 0xfe, 0x0d,
++      0xfd, 0xcd, 0x08, 0x72, 0x08, 0xd8, 0xc9, 0xbd, 0x05, 0xbc,
++      0xb0, 0x76, 0x70, 0xb1, 0x4c, 0x32, 0xbc, 0x6e, 0x1b, 0xc9,
++      0x11, 0xed, 0xf6, 0xa4, 0x5e, 0x72, 0xc0, 0x11, 0x65, 0xfd,
++      0x51, 0xb0, 0xb5, 0x27, 0x46, 0x53, 0x71, 0xba, 0xca, 0x69,
++      0x23, 0x4d, 0x08, 0x1b, 0x37, 0x10, 0x9a, 0x69, 0x31, 0x3c,
++      0x91, 0x37, 0xbb, 0xa5, 0x2b, 0xbb, 0xdd, 0xd0, 0xd0, 0x1a,
++      0xcb, 0x2c, 0x67, 0x23, 0xbd, 0xfa, 0xd1, 0xb3, 0x27, 0x7d,
++      0x84, 0x66, 0xca, 0x68, 0x9b, 0xce, 0x17, 0xda, 0x37, 0xcc,
++      0xdd, 0xdc, 0xd2, 0x2a, 0x03, 0x85, 0x37, 0x83, 0xae, 0x89,
++      0x93, 0x8a, 0x1d, 0x16, 0x34, 0xba, 0xd1, 0x79, 0x34, 0x3e,
++      0xed, 0xe3, 0xe9, 0xb0, 0x21, 0x16, 0xee, 0x07, 0x03, 0x53,
++      0x45, 0x19, 0x56, 0x06, 0x7a, 0x47, 0x05, 0x03, 0x77, 0x3b,
++      0x7a, 0x74, 0x07, 0x73, 0xc6, 0x1d, 0x4e, 0x64, 0xef, 0xae,
++      0x33, 0x54, 0x09, 0x87, 0x73, 0x2a, 0x38, 0xba, 0x22, 0x3b,
++      0xb4, 0x0b, 0x2c, 0x45, 0x80, 0xf9, 0xe1, 0x15, 0xb6, 0xa6,
++      0xe7, 0xb9, 0x39, 0xf7, 0xeb, 0x18, 0xba, 0xb7, 0xf4, 0xcb,
++      0x30, 0x60, 0xc7, 0xb0, 0x7f, 0x1a, 0x45, 0x87, 0x40, 0x85,
++      0x93, 0xe5, 0x13, 0x59, 0x84, 0xd3, 0xf4, 0x1b, 0x6f, 0xa0,
++      0x56, 0xfe, 0xf6, 0xae, 0x17, 0xc1, 0x47, 0x98, 0x5a, 0x3d,
++      0x4d, 0x2e, 0x88, 0x19, 0x62, 0xae, 0x5f, 0x1e, 0x8c, 0xdf,
++      0x9f, 0x27, 0x7a, 0xef, 0x1a, 0x69, 0x8f, 0x0c, 0xdb, 0x22,
++      0xd0, 0xde, 0x46, 0xc6, 0x69, 0xee, 0x2f, 0x34, 0x7f, 0x74,
++      0xdc, 0x6b, 0xf1, 0xfa, 0x5e, 0x7e, 0x7d, 0xa3, 0xd8, 0x39,
++      0x06, 0x59, 0x65, 0xa4, 0x1c, 0xb4, 0x23, 0xc6, 0xaa, 0xdd,
++      0x76, 0xf6, 0xbf, 0xa2, 0xc1, 0x1a, 0x26, 0x7a, 0x97, 0x11,
++      0x06, 0x22, 0x0f, 0x2e, 0xbf, 0xee, 0x78, 0xe1, 0xba, 0xf8,
++      0x53, 0x91, 0x64, 0x12, 0xdd, 0x12, 0x7b, 0xe5, 0x73, 0x70,
++      0x3b, 0x45, 0x05, 0x48, 0x39, 0x8d, 0xae, 0xf2, 0xe2, 0xfd,
++      0x6e, 0x06, 0x20, 0x1f, 0x85, 0x5f, 0xee, 0xe9, 0xfd, 0xca,
++      0x8c, 0x52, 0x2a, 0x76, 0x45, 0xdb, 0xb2, 0xf3, 0x97, 0x7e,
++      0x74, 0xb1, 0x61, 0x8d, 0x04, 0xe3, 0xcb, 0x48, 0xfb, 0xca,
++      0x93, 0xe6, 0x93, 0xec, 0xd0, 0xfd, 0x96, 0xd3, 0xf4, 0xde,
++      0x7e, 0x19, 0xcd, 0x66, 0xa3, 0xe9, 0xe2, 0xab, 0xd8, 0xff,
++      0xed, 0xd0, 0x5e, 0x8d, 0xaf, 0x47, 0x8f, 0xf3, 0xb1, 0x5d,
++      0x7c, 0x1c, 0xdb, 0x87, 0xd9, 0xfd, 0x87, 0xd9, 0xe8, 0x93,
++      0x9d, 0xcc, 0xc3, 0x4a, 0xec, 0x8d, 0xbd, 0x9d, 0x8d, 0xc7,
++      0xf6, 0xfe, 0xd6, 0x5e, 0x7f, 0x1c, 0xcd, 0x3e, 0x8c, 0x07,
++      0x7c, 0x6e, 0x36, 0xe6, 0x13, 0x31, 0x2d, 0x2e, 0xc8, 0x46,
++      0x04, 0xf0, 0xd4, 0xbd, 0xfc, 0x3c, 0xfe, 0x63, 0x31, 0x9e,
++      0x2e, 0xec, 0xc3, 0x78, 0xf6, 0x69, 0xb2, 0x58, 0x80, 0xda,
++      0xd5, 0x57, 0x3b, 0x7a, 0x78, 0x00, 0xf1, 0xd1, 0xd5, 0xdd,
++      0xd8, 0xde, 0x8d, 0xbe, 0x40, 0x9b, 0xe3, 0x3f, 0xae, 0xc7,
++      0x0f, 0x0b, 0xfb, 0xe5, 0xe3, 0x78, 0x6a, 0xee, 0x49, 0xfe,
++      0xcb, 0x04, 0xfc, 0xcc, 0x17, 0x23, 0xbe, 0x30, 0x99, 0xda,
++      0x2f, 0xb3, 0xc9, 0x62, 0x32, 0xfd, 0x20, 0x04, 0xb9, 0x85,
++      0x3b, 0x9b, 0x7c, 0xf8, 0xb8, 0xb0, 0x1f, 0xef, 0xef, 0x6e,
++      0xc6, 0x33, 0x59, 0xd5, 0xfd, 0x19, 0xa7, 0xcb, 0x8b, 0xf6,
++      0x61, 0x34, 0x5b, 0x4c, 0xc6, 0x73, 0x03, 0x3e, 0x3e, 0x4f,
++      0x6e, 0xfa, 0x42, 0xbd, 0x19, 0xcd, 0xc1, 0xf6, 0x1b, 0xfb,
++      0x65, 0xb2, 0xf8, 0x78, 0xff, 0xb8, 0x68, 0x99, 0xa7, 0x70,
++      0xa3, 0xe9, 0x57, 0xfb, 0xcf, 0xc9, 0xf4, 0x66, 0x60, 0xc7,
++      0x13, 0x21, 0x34, 0xfe, 0xe3, 0x61, 0x36, 0x9e, 0x43, 0x7e,
++      0x03, 0xda, 0x93, 0x4f, 0xe0, 0x78, 0x8c, 0x2f, 0x27, 0xd3,
++      0xeb, 0xbb, 0xc7, 0x1b, 0xd9, 0x02, 0xbe, 0x02, 0x85, 0xe9,
++      0xfd, 0x02, 0x7a, 0x82, 0x64, 0xe0, 0x73, 0x71, 0x2f, 0xaa,
++      0x09, 0xcf, 0x06, 0xea, 0x60, 0x06, 0xf4, 0xcd, 0xa7, 0xf1,
++      0x0c, 0xfa, 0x9b, 0x2e, 0x46, 0x57, 0x93, 0xbb, 0x09, 0x8e,
++      0xe4, 0xda, 0xf0, 0xed, 0x64, 0x31, 0xc5, 0x11, 0xb2, 0x5c,
++      0x3c, 0x52, 0xce, 0xaf, 0x1f, 0xef, 0x46, 0x10, 0xe2, 0x71,
++      0xf6, 0x70, 0x3f, 0x1f, 0x73, 0x7c, 0x43, 0x15, 0x82, 0x08,
++      0x14, 0x3e, 0x9b, 0xcc, 0xff, 0x69, 0x47, 0x73, 0xe3, 0x15,
++      0xfb, 0xfb, 0xe3, 0xa8, 0x25, 0x04, 0xed, 0x82, 0xc6, 0xa7,
++      0xd1, 0xf4, 0x5a, 0x0c, 0x75, 0x64, 0x48, 0x8a, 0x6b, 0xbf,
++      0xde, 0x3f, 0xb2, 0x6a, 0x40, 0xee, 0xbb, 0x1b, 0x3e, 0x60,
++      0xc2, 0x03, 0x54, 0xd4, 0xd8, 0xde, 0x8c, 0x6f, 0xc7, 0xd7,
++      0x8b, 0xc9, 0x67, 0x98, 0x17, 0x4f, 0xe2, 0x98, 0xf9, 0xe3,
++      0xa7, 0xb1, 0xd7, 0xf7, 0x7c, 0x21, 0x0a, 0xba, 0xbb, 0xb3,
++      0xd3, 0xf1, 0x35, 0xf8, 0x1d, 0xcd, 0xbe, 0xda, 0xf9, 0x78,
++      0xf6, 0x79, 0x72, 0x4d, 0x3d, 0x98, 0xd9, 0xf8, 0x61, 0x34,
++      0x81, 0xfa, 0xb9, 0x20, 0x3d, 0x9b, 0x91, 0xca, 0xfd, 0x54,
++      0x73, 0xcb, 0xbb, 0x21, 0x8d, 0x07, 0x2f, 0x19, 0x7f, 0xa6,
++      0x0f, 0x3c, 0x4e, 0xef, 0x28, 0xed, 0x6c, 0xfc, 0xfb, 0x23,
++      0xe4, 0x39, 0xe3, 0x09, 0xa4, 0x31, 0xfa, 0x00, 0x6f, 0xa3,
++      0x32, 0x23, 0xbb, 0x9b, 0x2f, 0x13, 0x1c, 0x4e, 0x0b, 0x1d,
++      0x1b, 0x7f, 0x20, 0xaf, 0xe0, 0x8b, 0xce, 0xf8, 0x5f, 0xe1,
++      0x46, 0xf7, 0xf6, 0xd3, 0xe8, 0xab, 0x6e, 0x65, 0x7f, 0xf5,
++      0xee, 0x01, 0x36, 0xdb, 0xb5, 0xed, 0xbe, 0x57, 0xc0, 0x29,
++      0x3a, 0xef, 0x1c, 0x5d, 0xdd, 0x53, 0x07, 0x57, 0xe0, 0x67,
++      0x22, 0x6c, 0x81, 0x11, 0x2a, 0x84, 0x26, 0xba, 0x19, 0x7d,
++      0x1a, 0x7d, 0x18, 0xcf, 0x07, 0xa6, 0x75, 0x02, 0x39, 0xda,
++      0x6f, 0x92, 0x0f, 0xec, 0xfc, 0x61, 0x7c, 0x3d, 0xe1, 0x5f,
++      0xf0, 0x3d, 0x5c, 0x0f, 0xb6, 0xbe, 0x53, 0xad, 0x20, 0x8a,
++      0x7e, 0x7f, 0xa4, 0x15, 0xf1, 0x81, 0x27, 0x62, 0x47, 0x30,
++      0x27, 0x45, 0xa3, 0x1f, 0x7a, 0x93, 0x31, 0x06, 0xe9, 0x6b,
++      0xd3, 0xe0, 0x23, 0x38, 0xfb, 0x38, 0x2e, 0x2f, 0xba, 0xb3,
++      0x8f, 0xfc, 0x8f, 0x7e, 0x71, 0x77, 0x3f, 0xa7, 0xb3, 0xe1,
++      0x90, 0xc5, 0xc8, 0x0a, 0xc7, 0xf8, 0xf3, 0x6a, 0xcc, 0xa7,
++      0x67, 0xe3, 0x29, 0xf4, 0x25, 0xe1, 0x34, 0xba, 0xbe, 0x7e,
++      0x9c, 0x21, 0xb4, 0xf8, 0x04, 0xdf, 0x00, 0x37, 0xf3, 0x47,
++      0x04, 0xdb, 0x64, 0x2a, 0x46, 0x31, 0x94, 0x57, 0xa2, 0x79,
++      0x32, 0xbb, 0x09, 0xf1, 0x24, 0x7a, 0xb6, 0xb7, 0xa3, 0xc9,
++      0xdd, 0xe3, 0xec, 0xc4, 0xc7, 0x70, 0xf2, 0x3d, 0x54, 0x48,
++      0x92, 0xe2, 0x6b, 0xad, 0x41, 0x82, 0x93, 0xcd, 0x2f, 0x07,
++      0xe2, 0x03, 0x76, 0x72, 0x8b, 0xa3, 0xae, 0x3f, 0x7a, 0xeb,
++      0xd9, 0x5e, 0xd4, 0x7e, 0xb5, 0x1f, 0x61, 0x8a, 0xab, 0x31,
++      0x1e, 0x1b, 0xdd, 0x7c, 0x9e, 0x30, 0xf3, 0xe8, 0x39, 0x06,
++      0xb1, 0x30, 0x9f, 0x78, 0x9d, 0xdc, 0x7b, 0x0a, 0x5e, 0x8f,
++      0xed, 0x4e, 0x3f, 0xa2, 0x44, 0x9f, 0x3f, 0xb3, 0xbd, 0x6f,
++      0xfe, 0x17, 0x84, 0xf3, 0x1b, 0xef, 0x12, 0x3b, 0x00, 0x00,
++      
++};
+Index: u-boot/include/configs/neo1973_gta01.h
+===================================================================
+--- u-boot.orig/include/configs/neo1973_gta01.h
++++ u-boot/include/configs/neo1973_gta01.h
+@@ -110,6 +110,7 @@
+                       CFG_CMD_MMC      | \
+                       CFG_CMD_FAT      | \
+                       CFG_CMD_EXT2     | \
++                      CFG_CMD_LICENSE  | \
+                       0)
+ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+ #include <cmd_confdefs.h>
+Index: u-boot/include/configs/hxd8.h
+===================================================================
+--- u-boot.orig/include/configs/hxd8.h
++++ u-boot/include/configs/hxd8.h
+@@ -110,6 +110,7 @@
+                       CFG_CMD_MMC      | \
+                       CFG_CMD_FAT      | \
+                       CFG_CMD_EXT2     | \
++                      CFG_CMD_LICENSE  | \
+                       0)
+ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+ #include <cmd_confdefs.h>
+Index: u-boot/include/configs/smdk2440.h
+===================================================================
+--- u-boot.orig/include/configs/smdk2440.h
++++ u-boot/include/configs/smdk2440.h
+@@ -110,6 +110,7 @@
+                       CFG_CMD_PORTIO   | \
+                       CFG_CMD_REGINFO  | \
+                       CFG_CMD_SAVES    | \
++                      CFG_CMD_LICENSE  | \
+                       CFG_CMD_USB)
+ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-machtypes.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-machtypes.patch
new file mode 100644 (file)
index 0000000..db3cee6
--- /dev/null
@@ -0,0 +1,4121 @@
+This adds a more recent version of mach-types.h to u-boot
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+
+Index: u-boot/include/asm-arm/mach-types.h
+===================================================================
+--- u-boot.orig/include/asm-arm/mach-types.h
++++ u-boot/include/asm-arm/mach-types.h
+@@ -424,7 +424,7 @@
+ #define MACH_TYPE_MPORT3S              411
+ #define MACH_TYPE_RA_ALPHA             412
+ #define MACH_TYPE_XCEP                 413
+-#define MACH_TYPE_ARCOM_MERCURY        414
++#define MACH_TYPE_ARCOM_VULCAN         414
+ #define MACH_TYPE_STARGATE             415
+ #define MACH_TYPE_ARMADILLOJ           416
+ #define MACH_TYPE_ELROY_JACK           417
+@@ -457,7 +457,7 @@
+ #define MACH_TYPE_XM250                444
+ #define MACH_TYPE_T6TC1XB              445
+ #define MACH_TYPE_ESS710               446
+-#define MACH_TYPE_MX3ADS               447
++#define MACH_TYPE_MX31ADS              447
+ #define MACH_TYPE_HIMALAYA             448
+ #define MACH_TYPE_BOLFENK              449
+ #define MACH_TYPE_AT91RM9200KR         450
+@@ -736,7 +736,311 @@
+ #define MACH_TYPE_LN2410SBC            725
+ #define MACH_TYPE_CB3RUFC              726
+ #define MACH_TYPE_MP2USB               727
+-#define MACH_TYPE_PDNB3               1002
++#define MACH_TYPE_NTNP425C             728
++#define MACH_TYPE_COLIBRI              729
++#define MACH_TYPE_PCM7220              730
++#define MACH_TYPE_GATEWAY7001          731
++#define MACH_TYPE_PCM027               732
++#define MACH_TYPE_CMPXA                733
++#define MACH_TYPE_ANUBIS               734
++#define MACH_TYPE_ITE8152              735
++#define MACH_TYPE_LPC3XXX              736
++#define MACH_TYPE_PUPPETEER            737
++#define MACH_TYPE_MACH_VADATECH        738
++#define MACH_TYPE_E570                 739
++#define MACH_TYPE_X50                  740
++#define MACH_TYPE_RECON                741
++#define MACH_TYPE_XBOARDGP8            742
++#define MACH_TYPE_FPIC2                743
++#define MACH_TYPE_AKITA                744
++#define MACH_TYPE_A81                  745
++#define MACH_TYPE_SVM_SC25X            746
++#define MACH_TYPE_VADATECH020          747
++#define MACH_TYPE_TLI                  748
++#define MACH_TYPE_EDB9315LC            749
++#define MACH_TYPE_PASSEC               750
++#define MACH_TYPE_DS_TIGER             751
++#define MACH_TYPE_E310                 752
++#define MACH_TYPE_E330                 753
++#define MACH_TYPE_RT3000               754
++#define MACH_TYPE_NOKIA770             755
++#define MACH_TYPE_PNX0106              756
++#define MACH_TYPE_HX21XX               757
++#define MACH_TYPE_FARADAY              758
++#define MACH_TYPE_SBC9312              759
++#define MACH_TYPE_BATMAN               760
++#define MACH_TYPE_JPD201               761
++#define MACH_TYPE_MIPSA                762
++#define MACH_TYPE_KACOM                763
++#define MACH_TYPE_SWARCOCPU            764
++#define MACH_TYPE_SWARCODSL            765
++#define MACH_TYPE_BLUEANGEL            766
++#define MACH_TYPE_HAIRYGRAMA           767
++#define MACH_TYPE_BANFF                768
++#define MACH_TYPE_CARMEVA              769
++#define MACH_TYPE_SAM255               770
++#define MACH_TYPE_PPM10                771
++#define MACH_TYPE_EDB9315A             772
++#define MACH_TYPE_SUNSET               773
++#define MACH_TYPE_STARGATE2            774
++#define MACH_TYPE_INTELMOTE2           775
++#define MACH_TYPE_TRIZEPS4             776
++#define MACH_TYPE_MAINSTONE2           777
++#define MACH_TYPE_EZ_IXP42X            778
++#define MACH_TYPE_TAPWAVE_ZODIAC       779
++#define MACH_TYPE_UNIVERSALMETER       780
++#define MACH_TYPE_HICOARM9             781
++#define MACH_TYPE_PNX4008              782
++#define MACH_TYPE_KWS6000              783
++#define MACH_TYPE_PORTUX920T           784
++#define MACH_TYPE_EZ_X5                785
++#define MACH_TYPE_OMAP_RUDOLPH         786
++#define MACH_TYPE_CPUAT91              787
++#define MACH_TYPE_REA9200              788
++#define MACH_TYPE_ACTS_PUNE_SA1110     789
++#define MACH_TYPE_IXP425               790
++#define MACH_TYPE_ARGONPLUSODYSSEY     791
++#define MACH_TYPE_PERCH                792
++#define MACH_TYPE_EIS05R1              793
++#define MACH_TYPE_PEPPERPAD            794
++#define MACH_TYPE_SB3010               795
++#define MACH_TYPE_RM9200               796
++#define MACH_TYPE_DMA03                797
++#define MACH_TYPE_ROAD_S101            798
++#define MACH_TYPE_IQ_NEXTGEN_A         799
++#define MACH_TYPE_IQ_NEXTGEN_B         800
++#define MACH_TYPE_IQ_NEXTGEN_C         801
++#define MACH_TYPE_IQ_NEXTGEN_D         802
++#define MACH_TYPE_IQ_NEXTGEN_E         803
++#define MACH_TYPE_MALLOW_AT91          804
++#define MACH_TYPE_CYBERTRACKER_I       805
++#define MACH_TYPE_GESBC931X            806
++#define MACH_TYPE_CENTIPAD             807
++#define MACH_TYPE_ARMSOC               808
++#define MACH_TYPE_SE4200               809
++#define MACH_TYPE_EMS197A              810
++#define MACH_TYPE_MICRO9               811
++#define MACH_TYPE_MICRO9L              812
++#define MACH_TYPE_UC5471DSP            813
++#define MACH_TYPE_SJ5471ENG            814
++#define MACH_TYPE_CMPXA26X             815
++#define MACH_TYPE_NC                   816
++#define MACH_TYPE_OMAP_PALMTE          817
++#define MACH_TYPE_AJAX52X              818
++#define MACH_TYPE_SIRIUSTAR            819
++#define MACH_TYPE_IODATA_HDLG          820
++#define MACH_TYPE_AT91RM9200UTL        821
++#define MACH_TYPE_BIOSAFE              822
++#define MACH_TYPE_MP1000               823
++#define MACH_TYPE_PARSY                824
++#define MACH_TYPE_CCXP                 825
++#define MACH_TYPE_OMAP_GSAMPLE         826
++#define MACH_TYPE_REALVIEW_EB          827
++#define MACH_TYPE_SAMOA                828
++#define MACH_TYPE_T3XSCALE             829
++#define MACH_TYPE_I878                 830
++#define MACH_TYPE_BORZOI               831
++#define MACH_TYPE_GECKO                832
++#define MACH_TYPE_DS101                833
++#define MACH_TYPE_OMAP_PALMTT2         834
++#define MACH_TYPE_XSCALE_PALMLD        835
++#define MACH_TYPE_CC9C                 836
++#define MACH_TYPE_SBC1670              837
++#define MACH_TYPE_IXDP28X5             838
++#define MACH_TYPE_OMAP_PALMTT          839
++#define MACH_TYPE_ML696K               840
++#define MACH_TYPE_ARCOM_ZEUS           841
++#define MACH_TYPE_OSIRIS               842
++#define MACH_TYPE_MAESTRO              843
++#define MACH_TYPE_TUNGE2               844
++#define MACH_TYPE_IXBBM                845
++#define MACH_TYPE_MX27                 846
++#define MACH_TYPE_AX8004               847
++#define MACH_TYPE_AT91SAM9261EK        848
++#define MACH_TYPE_LOFT                 849
++#define MACH_TYPE_MAGPIE               850
++#define MACH_TYPE_MX21                 851
++#define MACH_TYPE_MB87M3400            852
++#define MACH_TYPE_MGUARD_DELTA         853
++#define MACH_TYPE_DAVINCI_DVDP         854
++#define MACH_TYPE_HTCUNIVERSAL         855
++#define MACH_TYPE_TPAD                 856
++#define MACH_TYPE_ROVERP3              857
++#define MACH_TYPE_JORNADA928           858
++#define MACH_TYPE_MV88FXX81            859
++#define MACH_TYPE_STMP36XX             860
++#define MACH_TYPE_SXNI79524            861
++#define MACH_TYPE_AMS_DELTA            862
++#define MACH_TYPE_URANIUM              863
++#define MACH_TYPE_UCON                 864
++#define MACH_TYPE_NAS100D              865
++#define MACH_TYPE_L083_1000            866
++#define MACH_TYPE_EZX                  867
++#define MACH_TYPE_PNX5220              868
++#define MACH_TYPE_BUTTE                869
++#define MACH_TYPE_SRM2                 870
++#define MACH_TYPE_DSBR                 871
++#define MACH_TYPE_CRYSTALBALL          872
++#define MACH_TYPE_TINYPXA27X           873
++#define MACH_TYPE_HERBIE               874
++#define MACH_TYPE_MAGICIAN             875
++#define MACH_TYPE_CM4002               876
++#define MACH_TYPE_B4                   877
++#define MACH_TYPE_MAUI                 878
++#define MACH_TYPE_CYBERTRACKER_G       879
++#define MACH_TYPE_NXDKN                880
++#define MACH_TYPE_MIO8390              881
++#define MACH_TYPE_OMI_BOARD            882
++#define MACH_TYPE_MX21CIV              883
++#define MACH_TYPE_MAHI_CDAC            884
++#define MACH_TYPE_XSCALE_PALMTX        885
++#define MACH_TYPE_S3C2413              887
++#define MACH_TYPE_SAMSYS_EP0           888
++#define MACH_TYPE_WG302V1              889
++#define MACH_TYPE_WG302V2              890
++#define MACH_TYPE_EB42X                891
++#define MACH_TYPE_IQ331ES              892
++#define MACH_TYPE_COSYDSP              893
++#define MACH_TYPE_UPLAT7D              894
++#define MACH_TYPE_PTDAVINCI            895
++#define MACH_TYPE_MBUS                 896
++#define MACH_TYPE_NADIA2VB             897
++#define MACH_TYPE_R1000                898
++#define MACH_TYPE_HW90250              899
++#define MACH_TYPE_OMAP_2430SDP         900
++#define MACH_TYPE_DAVINCI_EVM          901
++#define MACH_TYPE_OMAP_TORNADO         902
++#define MACH_TYPE_OLOCREEK             903
++#define MACH_TYPE_PALMZ72              904
++#define MACH_TYPE_NXDB500              905
++#define MACH_TYPE_APF9328              906
++#define MACH_TYPE_OMAP_WIPOQ           907
++#define MACH_TYPE_OMAP_TWIP            908
++#define MACH_TYPE_XSCALE_PALMTREO650   909
++#define MACH_TYPE_ACUMEN               910
++#define MACH_TYPE_XP100                911
++#define MACH_TYPE_FS2410               912
++#define MACH_TYPE_PXA270_CERF          913
++#define MACH_TYPE_SQ2FTLPALM           914
++#define MACH_TYPE_BSEMSERVER           915
++#define MACH_TYPE_NETCLIENT            916
++#define MACH_TYPE_XSCALE_PALMTT5       917
++#define MACH_TYPE_OMAP_PALMTC          918
++#define MACH_TYPE_OMAP_APOLLON         919
++#define MACH_TYPE_ARGONLVEVB           920
++#define MACH_TYPE_REA_2D               921
++#define MACH_TYPE_TI3E524              922
++#define MACH_TYPE_ATEB9200             923
++#define MACH_TYPE_AUCKLAND             924
++#define MACH_TYPE_AK3320M              925
++#define MACH_TYPE_DURAMAX              926
++#define MACH_TYPE_N35                  927
++#define MACH_TYPE_PRONGHORN            928
++#define MACH_TYPE_FUNDY                929
++#define MACH_TYPE_LOGICPD_PXA270       930
++#define MACH_TYPE_CPU777               931
++#define MACH_TYPE_SIMICON9201          932
++#define MACH_TYPE_LEAP2_HPM            933
++#define MACH_TYPE_CM922TXA10           934
++#define MACH_TYPE_PXA                  935
++#define MACH_TYPE_SANDGATE2            936
++#define MACH_TYPE_SANDGATE2G           937
++#define MACH_TYPE_SANDGATE2P           938
++#define MACH_TYPE_FRED_JACK            939
++#define MACH_TYPE_TTG_COLOR1           940
++#define MACH_TYPE_NXEB500HMI           941
++#define MACH_TYPE_NETDCU8              942
++#define MACH_TYPE_ML675050_CPU_BOA     943
++#define MACH_TYPE_NG_FVX538            944
++#define MACH_TYPE_NG_FVS338            945
++#define MACH_TYPE_PNX4103              946
++#define MACH_TYPE_HESDB                947
++#define MACH_TYPE_XSILO                948
++#define MACH_TYPE_ESPRESSO             949
++#define MACH_TYPE_EMLC                 950
++#define MACH_TYPE_SISTERON             951
++#define MACH_TYPE_RX1950               952
++#define MACH_TYPE_TSC_VENUS            953
++#define MACH_TYPE_DS101J               954
++#define MACH_TYPE_MXC30030ADS          955
++#define MACH_TYPE_FUJITSU_WIMAXSOC     956
++#define MACH_TYPE_DUALPCMODEM          957
++#define MACH_TYPE_GESBC9312            958
++#define MACH_TYPE_HTCAPACHE            959
++#define MACH_TYPE_IXDP435              960
++#define MACH_TYPE_CATPROVT100          961
++#define MACH_TYPE_PICOTUX1XX           962
++#define MACH_TYPE_PICOTUX2XX           963
++#define MACH_TYPE_DSMG600              964
++#define MACH_TYPE_EMPC2                965
++#define MACH_TYPE_VENTURA              966
++#define MACH_TYPE_PHIDGET_SBC          967
++#define MACH_TYPE_IJ3K                 968
++#define MACH_TYPE_PISGAH               969
++#define MACH_TYPE_OMAP_FSAMPLE         970
++#define MACH_TYPE_SG720                971
++#define MACH_TYPE_REDFOX               972
++#define MACH_TYPE_MYSH_EP9315_1        973
++#define MACH_TYPE_TPF106               974
++#define MACH_TYPE_AT91RM9200KG         975
++#define MACH_TYPE_SLEDB                976
++#define MACH_TYPE_ONTRACK              977
++#define MACH_TYPE_PM1200               978
++#define MACH_TYPE_ESS24XXX             979
++#define MACH_TYPE_COREMP7              980
++#define MACH_TYPE_NEXCODER_6446        981
++#define MACH_TYPE_STVC8380             982
++#define MACH_TYPE_TEKLYNX              983
++#define MACH_TYPE_CARBONADO            984
++#define MACH_TYPE_SYSMOS_MP730         985
++#define MACH_TYPE_SNAPPER_CL15         986
++#define MACH_TYPE_PGIGIM               987
++#define MACH_TYPE_PTX9160P2            988
++#define MACH_TYPE_DCORE1               989
++#define MACH_TYPE_VICTORPXA            990
++#define MACH_TYPE_MX2DTB               991
++#define MACH_TYPE_PXA_IREX_ER0100      992
++#define MACH_TYPE_OMAP_PALMZ71         993
++#define MACH_TYPE_BARTEC_DEG           994
++#define MACH_TYPE_HW50251              995
++#define MACH_TYPE_IBOX                 996
++#define MACH_TYPE_ATLASLH7A404         997
++#define MACH_TYPE_PT2026               998
++#define MACH_TYPE_HTCALPINE            999
++#define MACH_TYPE_BARTEC_VTU           1000
++#define MACH_TYPE_VCOREII              1001
++#define MACH_TYPE_PDNB3                1002
++#define MACH_TYPE_HTCBEETLES           1003
++#define MACH_TYPE_S3C6400              1004
++#define MACH_TYPE_S3C2443              1005
++#define MACH_TYPE_OMAP_LDK             1006
++#define MACH_TYPE_SMDK2460             1007
++#define MACH_TYPE_SMDK2440             1008
++#define MACH_TYPE_SMDK2412             1009
++#define MACH_TYPE_WEBBOX               1010
++#define MACH_TYPE_CWWNDP               1011
++#define MACH_TYPE_DRAGON               1012
++#define MACH_TYPE_OPENDO_CPU_BOARD     1013
++#define MACH_TYPE_CCM2200              1014
++#define MACH_TYPE_ETWARM               1015
++#define MACH_TYPE_M93030               1016
++#define MACH_TYPE_CC7U                 1017
++#define MACH_TYPE_MTT_RANGER           1018
++#define MACH_TYPE_NEXUS                1019
++#define MACH_TYPE_DESMAN               1020
++#define MACH_TYPE_BKDE303              1021
++#define MACH_TYPE_SMDK2413             1022
++#define MACH_TYPE_AML_M7200            1023
++#define MACH_TYPE_AML_M5900            1024
++#define MACH_TYPE_SG640                1025
++#define MACH_TYPE_EDG79524             1026
++#define MACH_TYPE_AI2410               1027
++#define MACH_TYPE_IXP465               1028
++#define MACH_TYPE_BALLOON3             1029
++#define MACH_TYPE_QT2410               1108
++#define MACH_TYPE_NEO1973_GTA01        1182
++#define MACH_TYPE_HXD8                 1303
++#define MACH_TYPE_NEO1973_GTA02        1304
+ #ifdef CONFIG_ARCH_EBSA110
+ # ifdef machine_arch_type
+@@ -3541,9 +3845,9 @@
+ # else
+ #  define machine_arch_type   MACH_TYPE_RAMSES
+ # endif
+-# define machine_is_ramses()  (machine_arch_type == MACH_TYPE_RAMSES)
++# define machine_is_mnci()    (machine_arch_type == MACH_TYPE_RAMSES)
+ #else
+-# define machine_is_ramses()  (0)
++# define machine_is_mnci()    (0)
+ #endif
+ #ifdef CONFIG_ARCH_S28X
+@@ -4501,9 +4805,9 @@
+ # else
+ #  define machine_arch_type   MACH_TYPE_M825XX
+ # endif
+-# define machine_is_m825xx()  (machine_arch_type == MACH_TYPE_M825XX)
++# define machine_is_comcerto()        (machine_arch_type == MACH_TYPE_M825XX)
+ #else
+-# define machine_is_m825xx()  (0)
++# define machine_is_comcerto()        (0)
+ #endif
+ #ifdef CONFIG_SA1100_M7100
+@@ -5658,16 +5962,16 @@
+ # define machine_is_xcep()    (0)
+ #endif
+-#ifdef CONFIG_MACH_ARCOM_MERCURY
++#ifdef CONFIG_MACH_ARCOM_VULCAN
+ # ifdef machine_arch_type
+ #  undef machine_arch_type
+ #  define machine_arch_type   __machine_arch_type
+ # else
+-#  define machine_arch_type   MACH_TYPE_ARCOM_MERCURY
++#  define machine_arch_type   MACH_TYPE_ARCOM_VULCAN
+ # endif
+-# define machine_is_arcom_mercury()   (machine_arch_type == MACH_TYPE_ARCOM_MERCURY)
++# define machine_is_arcom_vulcan()    (machine_arch_type == MACH_TYPE_ARCOM_VULCAN)
+ #else
+-# define machine_is_arcom_mercury()   (0)
++# define machine_is_arcom_vulcan()    (0)
+ #endif
+ #ifdef CONFIG_MACH_STARGATE
+@@ -6054,16 +6358,16 @@
+ # define machine_is_ess710()  (0)
+ #endif
+-#ifdef CONFIG_MACH_MX3ADS
++#ifdef CONFIG_MACH_MX31ADS
+ # ifdef machine_arch_type
+ #  undef machine_arch_type
+ #  define machine_arch_type   __machine_arch_type
+ # else
+-#  define machine_arch_type   MACH_TYPE_MX3ADS
++#  define machine_arch_type   MACH_TYPE_MX31ADS
+ # endif
+-# define machine_is_mx3ads()  (machine_arch_type == MACH_TYPE_MX3ADS)
++# define machine_is_mx31ads() (machine_arch_type == MACH_TYPE_MX31ADS)
+ #else
+-# define machine_is_mx3ads()  (0)
++# define machine_is_mx31ads() (0)
+ #endif
+ #ifdef CONFIG_MACH_HIMALAYA
+@@ -7333,9 +7637,9 @@
+ # else
+ #  define machine_arch_type   MACH_TYPE_ARGONPLUSEVB
+ # endif
+-# define machine_is_argonplusevb()    (machine_arch_type == MACH_TYPE_ARGONPLUSEVB)
++# define machine_is_i30030evb()       (machine_arch_type == MACH_TYPE_ARGONPLUSEVB)
+ #else
+-# define machine_is_argonplusevb()    (0)
++# define machine_is_i30030evb()       (0)
+ #endif
+ #ifdef CONFIG_MACH_SCMA11EVB
+@@ -7345,9 +7649,9 @@
+ # else
+ #  define machine_arch_type   MACH_TYPE_SCMA11EVB
+ # endif
+-# define machine_is_scma11evb()       (machine_arch_type == MACH_TYPE_SCMA11EVB)
++# define machine_is_mxc27530evb()     (machine_arch_type == MACH_TYPE_SCMA11EVB)
+ #else
+-# define machine_is_scma11evb()       (0)
++# define machine_is_mxc27530evb()     (0)
+ #endif
+ #ifdef CONFIG_MACH_SMDK2800
+@@ -8305,9 +8609,9 @@
+ # else
+ #  define machine_arch_type   MACH_TYPE_SCMA11BB
+ # endif
+-# define machine_is_scma11bb()        (machine_arch_type == MACH_TYPE_SCMA11BB)
++# define machine_is_mxc27530ads()     (machine_arch_type == MACH_TYPE_SCMA11BB)
+ #else
+-# define machine_is_scma11bb()        (0)
++# define machine_is_mxc27530ads()     (0)
+ #endif
+ #ifdef CONFIG_MACH_TRIZEPS3
+@@ -9193,9 +9497,9 @@
+ # else
+ #  define machine_arch_type   MACH_TYPE_ZEUSEVB
+ # endif
+-# define machine_is_zeusevb() (machine_arch_type == MACH_TYPE_ZEUSEVB)
++# define machine_is_mxc91131evb()     (machine_arch_type == MACH_TYPE_ZEUSEVB)
+ #else
+-# define machine_is_zeusevb() (0)
++# define machine_is_mxc91131evb()     (0)
+ #endif
+ #ifdef CONFIG_MACH_P700
+@@ -9402,6 +9706,3667 @@
+ # define machine_is_mp2usb()  (0)
+ #endif
++#ifdef CONFIG_MACH_NTNP425C
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NTNP425C
++# endif
++# define machine_is_ntnp425c()        (machine_arch_type == MACH_TYPE_NTNP425C)
++#else
++# define machine_is_ntnp425c()        (0)
++#endif
++
++#ifdef CONFIG_MACH_COLIBRI
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_COLIBRI
++# endif
++# define machine_is_colibri() (machine_arch_type == MACH_TYPE_COLIBRI)
++#else
++# define machine_is_colibri() (0)
++#endif
++
++#ifdef CONFIG_MACH_PCM7220
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PCM7220
++# endif
++# define machine_is_pcm7220() (machine_arch_type == MACH_TYPE_PCM7220)
++#else
++# define machine_is_pcm7220() (0)
++#endif
++
++#ifdef CONFIG_MACH_GATEWAY7001
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_GATEWAY7001
++# endif
++# define machine_is_gateway7001()     (machine_arch_type == MACH_TYPE_GATEWAY7001)
++#else
++# define machine_is_gateway7001()     (0)
++#endif
++
++#ifdef CONFIG_MACH_PCM027
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PCM027
++# endif
++# define machine_is_pcm027()  (machine_arch_type == MACH_TYPE_PCM027)
++#else
++# define machine_is_pcm027()  (0)
++#endif
++
++#ifdef CONFIG_MACH_CMPXA
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CMPXA
++# endif
++# define machine_is_cmpxa()   (machine_arch_type == MACH_TYPE_CMPXA)
++#else
++# define machine_is_cmpxa()   (0)
++#endif
++
++#ifdef CONFIG_MACH_ANUBIS
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ANUBIS
++# endif
++# define machine_is_anubis()  (machine_arch_type == MACH_TYPE_ANUBIS)
++#else
++# define machine_is_anubis()  (0)
++#endif
++
++#ifdef CONFIG_MACH_ITE8152
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ITE8152
++# endif
++# define machine_is_ite8152() (machine_arch_type == MACH_TYPE_ITE8152)
++#else
++# define machine_is_ite8152() (0)
++#endif
++
++#ifdef CONFIG_MACH_LPC3XXX
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_LPC3XXX
++# endif
++# define machine_is_lpc3xxx() (machine_arch_type == MACH_TYPE_LPC3XXX)
++#else
++# define machine_is_lpc3xxx() (0)
++#endif
++
++#ifdef CONFIG_MACH_PUPPETEER
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PUPPETEER
++# endif
++# define machine_is_puppeteer()       (machine_arch_type == MACH_TYPE_PUPPETEER)
++#else
++# define machine_is_puppeteer()       (0)
++#endif
++
++#ifdef CONFIG_MACH_MACH_VADATECH
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MACH_VADATECH
++# endif
++# define machine_is_vt001()   (machine_arch_type == MACH_TYPE_MACH_VADATECH)
++#else
++# define machine_is_vt001()   (0)
++#endif
++
++#ifdef CONFIG_MACH_E570
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_E570
++# endif
++# define machine_is_e570()    (machine_arch_type == MACH_TYPE_E570)
++#else
++# define machine_is_e570()    (0)
++#endif
++
++#ifdef CONFIG_MACH_X50
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_X50
++# endif
++# define machine_is_x50()     (machine_arch_type == MACH_TYPE_X50)
++#else
++# define machine_is_x50()     (0)
++#endif
++
++#ifdef CONFIG_MACH_RECON
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_RECON
++# endif
++# define machine_is_recon()   (machine_arch_type == MACH_TYPE_RECON)
++#else
++# define machine_is_recon()   (0)
++#endif
++
++#ifdef CONFIG_MACH_XBOARDGP8
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_XBOARDGP8
++# endif
++# define machine_is_xboardgp8()       (machine_arch_type == MACH_TYPE_XBOARDGP8)
++#else
++# define machine_is_xboardgp8()       (0)
++#endif
++
++#ifdef CONFIG_MACH_FPIC2
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_FPIC2
++# endif
++# define machine_is_fpic2()   (machine_arch_type == MACH_TYPE_FPIC2)
++#else
++# define machine_is_fpic2()   (0)
++#endif
++
++#ifdef CONFIG_MACH_AKITA
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_AKITA
++# endif
++# define machine_is_akita()   (machine_arch_type == MACH_TYPE_AKITA)
++#else
++# define machine_is_akita()   (0)
++#endif
++
++#ifdef CONFIG_MACH_A81
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_A81
++# endif
++# define machine_is_a81()     (machine_arch_type == MACH_TYPE_A81)
++#else
++# define machine_is_a81()     (0)
++#endif
++
++#ifdef CONFIG_MACH_SVM_SC25X
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SVM_SC25X
++# endif
++# define machine_is_svm_sc25x()       (machine_arch_type == MACH_TYPE_SVM_SC25X)
++#else
++# define machine_is_svm_sc25x()       (0)
++#endif
++
++#ifdef CONFIG_MACH_VADATECH020
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_VADATECH020
++# endif
++# define machine_is_vt020()   (machine_arch_type == MACH_TYPE_VADATECH020)
++#else
++# define machine_is_vt020()   (0)
++#endif
++
++#ifdef CONFIG_MACH_TLI
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_TLI
++# endif
++# define machine_is_tli()     (machine_arch_type == MACH_TYPE_TLI)
++#else
++# define machine_is_tli()     (0)
++#endif
++
++#ifdef CONFIG_MACH_EDB9315LC
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_EDB9315LC
++# endif
++# define machine_is_edb9315lc()       (machine_arch_type == MACH_TYPE_EDB9315LC)
++#else
++# define machine_is_edb9315lc()       (0)
++#endif
++
++#ifdef CONFIG_MACH_PASSEC
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PASSEC
++# endif
++# define machine_is_passec()  (machine_arch_type == MACH_TYPE_PASSEC)
++#else
++# define machine_is_passec()  (0)
++#endif
++
++#ifdef CONFIG_MACH_DS_TIGER
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_DS_TIGER
++# endif
++# define machine_is_ds_tiger()        (machine_arch_type == MACH_TYPE_DS_TIGER)
++#else
++# define machine_is_ds_tiger()        (0)
++#endif
++
++#ifdef CONFIG_MACH_E310
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_E310
++# endif
++# define machine_is_e310()    (machine_arch_type == MACH_TYPE_E310)
++#else
++# define machine_is_e310()    (0)
++#endif
++
++#ifdef CONFIG_MACH_E330
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_E330
++# endif
++# define machine_is_e330()    (machine_arch_type == MACH_TYPE_E330)
++#else
++# define machine_is_e330()    (0)
++#endif
++
++#ifdef CONFIG_MACH_RT3000
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_RT3000
++# endif
++# define machine_is_rt3000()  (machine_arch_type == MACH_TYPE_RT3000)
++#else
++# define machine_is_rt3000()  (0)
++#endif
++
++#ifdef CONFIG_MACH_NOKIA770
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NOKIA770
++# endif
++# define machine_is_nokia770()        (machine_arch_type == MACH_TYPE_NOKIA770)
++#else
++# define machine_is_nokia770()        (0)
++#endif
++
++#ifdef CONFIG_MACH_PNX0106
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PNX0106
++# endif
++# define machine_is_pnx0106() (machine_arch_type == MACH_TYPE_PNX0106)
++#else
++# define machine_is_pnx0106() (0)
++#endif
++
++#ifdef CONFIG_MACH_HX21XX
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_HX21XX
++# endif
++# define machine_is_hx21xx()  (machine_arch_type == MACH_TYPE_HX21XX)
++#else
++# define machine_is_hx21xx()  (0)
++#endif
++
++#ifdef CONFIG_MACH_FARADAY
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_FARADAY
++# endif
++# define machine_is_faraday() (machine_arch_type == MACH_TYPE_FARADAY)
++#else
++# define machine_is_faraday() (0)
++#endif
++
++#ifdef CONFIG_MACH_SBC9312
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SBC9312
++# endif
++# define machine_is_sbc9312() (machine_arch_type == MACH_TYPE_SBC9312)
++#else
++# define machine_is_sbc9312() (0)
++#endif
++
++#ifdef CONFIG_MACH_BATMAN
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_BATMAN
++# endif
++# define machine_is_batman()  (machine_arch_type == MACH_TYPE_BATMAN)
++#else
++# define machine_is_batman()  (0)
++#endif
++
++#ifdef CONFIG_MACH_JPD201
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_JPD201
++# endif
++# define machine_is_jpd201()  (machine_arch_type == MACH_TYPE_JPD201)
++#else
++# define machine_is_jpd201()  (0)
++#endif
++
++#ifdef CONFIG_MACH_MIPSA
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MIPSA
++# endif
++# define machine_is_mipsa()   (machine_arch_type == MACH_TYPE_MIPSA)
++#else
++# define machine_is_mipsa()   (0)
++#endif
++
++#ifdef CONFIG_MACH_KACOM
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_KACOM
++# endif
++# define machine_is_kacom()   (machine_arch_type == MACH_TYPE_KACOM)
++#else
++# define machine_is_kacom()   (0)
++#endif
++
++#ifdef CONFIG_MACH_SWARCOCPU
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SWARCOCPU
++# endif
++# define machine_is_swarcocpu()       (machine_arch_type == MACH_TYPE_SWARCOCPU)
++#else
++# define machine_is_swarcocpu()       (0)
++#endif
++
++#ifdef CONFIG_MACH_SWARCODSL
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SWARCODSL
++# endif
++# define machine_is_swarcodsl()       (machine_arch_type == MACH_TYPE_SWARCODSL)
++#else
++# define machine_is_swarcodsl()       (0)
++#endif
++
++#ifdef CONFIG_MACH_BLUEANGEL
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_BLUEANGEL
++# endif
++# define machine_is_blueangel()       (machine_arch_type == MACH_TYPE_BLUEANGEL)
++#else
++# define machine_is_blueangel()       (0)
++#endif
++
++#ifdef CONFIG_MACH_HAIRYGRAMA
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_HAIRYGRAMA
++# endif
++# define machine_is_hairygrama()      (machine_arch_type == MACH_TYPE_HAIRYGRAMA)
++#else
++# define machine_is_hairygrama()      (0)
++#endif
++
++#ifdef CONFIG_MACH_BANFF
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_BANFF
++# endif
++# define machine_is_banff()   (machine_arch_type == MACH_TYPE_BANFF)
++#else
++# define machine_is_banff()   (0)
++#endif
++
++#ifdef CONFIG_MACH_CARMEVA
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CARMEVA
++# endif
++# define machine_is_carmeva() (machine_arch_type == MACH_TYPE_CARMEVA)
++#else
++# define machine_is_carmeva() (0)
++#endif
++
++#ifdef CONFIG_MACH_SAM255
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SAM255
++# endif
++# define machine_is_sam255()  (machine_arch_type == MACH_TYPE_SAM255)
++#else
++# define machine_is_sam255()  (0)
++#endif
++
++#ifdef CONFIG_MACH_PPM10
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PPM10
++# endif
++# define machine_is_ppm10()   (machine_arch_type == MACH_TYPE_PPM10)
++#else
++# define machine_is_ppm10()   (0)
++#endif
++
++#ifdef CONFIG_MACH_EDB9315A
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_EDB9315A
++# endif
++# define machine_is_edb9315a()        (machine_arch_type == MACH_TYPE_EDB9315A)
++#else
++# define machine_is_edb9315a()        (0)
++#endif
++
++#ifdef CONFIG_MACH_SUNSET
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SUNSET
++# endif
++# define machine_is_sunset()  (machine_arch_type == MACH_TYPE_SUNSET)
++#else
++# define machine_is_sunset()  (0)
++#endif
++
++#ifdef CONFIG_MACH_STARGATE2
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_STARGATE2
++# endif
++# define machine_is_stargate2()       (machine_arch_type == MACH_TYPE_STARGATE2)
++#else
++# define machine_is_stargate2()       (0)
++#endif
++
++#ifdef CONFIG_MACH_INTELMOTE2
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_INTELMOTE2
++# endif
++# define machine_is_intelmote2()      (machine_arch_type == MACH_TYPE_INTELMOTE2)
++#else
++# define machine_is_intelmote2()      (0)
++#endif
++
++#ifdef CONFIG_MACH_TRIZEPS4
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_TRIZEPS4
++# endif
++# define machine_is_trizeps4()        (machine_arch_type == MACH_TYPE_TRIZEPS4)
++#else
++# define machine_is_trizeps4()        (0)
++#endif
++
++#ifdef CONFIG_MACH_MAINSTONE2
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MAINSTONE2
++# endif
++# define machine_is_mainstone2()      (machine_arch_type == MACH_TYPE_MAINSTONE2)
++#else
++# define machine_is_mainstone2()      (0)
++#endif
++
++#ifdef CONFIG_MACH_EZ_IXP42X
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_EZ_IXP42X
++# endif
++# define machine_is_ez_ixp42x()       (machine_arch_type == MACH_TYPE_EZ_IXP42X)
++#else
++# define machine_is_ez_ixp42x()       (0)
++#endif
++
++#ifdef CONFIG_MACH_TAPWAVE_ZODIAC
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_TAPWAVE_ZODIAC
++# endif
++# define machine_is_tapwave_zodiac()  (machine_arch_type == MACH_TYPE_TAPWAVE_ZODIAC)
++#else
++# define machine_is_tapwave_zodiac()  (0)
++#endif
++
++#ifdef CONFIG_MACH_UNIVERSALMETER
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_UNIVERSALMETER
++# endif
++# define machine_is_universalmeter()  (machine_arch_type == MACH_TYPE_UNIVERSALMETER)
++#else
++# define machine_is_universalmeter()  (0)
++#endif
++
++#ifdef CONFIG_MACH_HICOARM9
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_HICOARM9
++# endif
++# define machine_is_hicoarm9()        (machine_arch_type == MACH_TYPE_HICOARM9)
++#else
++# define machine_is_hicoarm9()        (0)
++#endif
++
++#ifdef CONFIG_MACH_PNX4008
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PNX4008
++# endif
++# define machine_is_pnx4008() (machine_arch_type == MACH_TYPE_PNX4008)
++#else
++# define machine_is_pnx4008() (0)
++#endif
++
++#ifdef CONFIG_MACH_KWS6000
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_KWS6000
++# endif
++# define machine_is_kws6000() (machine_arch_type == MACH_TYPE_KWS6000)
++#else
++# define machine_is_kws6000() (0)
++#endif
++
++#ifdef CONFIG_MACH_PORTUX920T
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PORTUX920T
++# endif
++# define machine_is_portux920t()      (machine_arch_type == MACH_TYPE_PORTUX920T)
++#else
++# define machine_is_portux920t()      (0)
++#endif
++
++#ifdef CONFIG_MACH_EZ_X5
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_EZ_X5
++# endif
++# define machine_is_ez_x5()   (machine_arch_type == MACH_TYPE_EZ_X5)
++#else
++# define machine_is_ez_x5()   (0)
++#endif
++
++#ifdef CONFIG_MACH_OMAP_RUDOLPH
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMAP_RUDOLPH
++# endif
++# define machine_is_omap_rudolph()    (machine_arch_type == MACH_TYPE_OMAP_RUDOLPH)
++#else
++# define machine_is_omap_rudolph()    (0)
++#endif
++
++#ifdef CONFIG_MACH_CPUAT91
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CPUAT91
++# endif
++# define machine_is_cpuat91() (machine_arch_type == MACH_TYPE_CPUAT91)
++#else
++# define machine_is_cpuat91() (0)
++#endif
++
++#ifdef CONFIG_MACH_REA9200
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_REA9200
++# endif
++# define machine_is_rea9200() (machine_arch_type == MACH_TYPE_REA9200)
++#else
++# define machine_is_rea9200() (0)
++#endif
++
++#ifdef CONFIG_MACH_ACTS_PUNE_SA1110
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ACTS_PUNE_SA1110
++# endif
++# define machine_is_acts_pune_sa1110()        (machine_arch_type == MACH_TYPE_ACTS_PUNE_SA1110)
++#else
++# define machine_is_acts_pune_sa1110()        (0)
++#endif
++
++#ifdef CONFIG_MACH_IXP425
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_IXP425
++# endif
++# define machine_is_ixp425()  (machine_arch_type == MACH_TYPE_IXP425)
++#else
++# define machine_is_ixp425()  (0)
++#endif
++
++#ifdef CONFIG_MACH_ARGONPLUSODYSSEY
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ARGONPLUSODYSSEY
++# endif
++# define machine_is_i30030ads()       (machine_arch_type == MACH_TYPE_ARGONPLUSODYSSEY)
++#else
++# define machine_is_i30030ads()       (0)
++#endif
++
++#ifdef CONFIG_MACH_PERCH
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PERCH
++# endif
++# define machine_is_perch()   (machine_arch_type == MACH_TYPE_PERCH)
++#else
++# define machine_is_perch()   (0)
++#endif
++
++#ifdef CONFIG_MACH_EIS05R1
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_EIS05R1
++# endif
++# define machine_is_eis05r1() (machine_arch_type == MACH_TYPE_EIS05R1)
++#else
++# define machine_is_eis05r1() (0)
++#endif
++
++#ifdef CONFIG_MACH_PEPPERPAD
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PEPPERPAD
++# endif
++# define machine_is_pepperpad()       (machine_arch_type == MACH_TYPE_PEPPERPAD)
++#else
++# define machine_is_pepperpad()       (0)
++#endif
++
++#ifdef CONFIG_MACH_SB3010
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SB3010
++# endif
++# define machine_is_sb3010()  (machine_arch_type == MACH_TYPE_SB3010)
++#else
++# define machine_is_sb3010()  (0)
++#endif
++
++#ifdef CONFIG_MACH_RM9200
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_RM9200
++# endif
++# define machine_is_rm9200()  (machine_arch_type == MACH_TYPE_RM9200)
++#else
++# define machine_is_rm9200()  (0)
++#endif
++
++#ifdef CONFIG_MACH_DMA03
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_DMA03
++# endif
++# define machine_is_dma03()   (machine_arch_type == MACH_TYPE_DMA03)
++#else
++# define machine_is_dma03()   (0)
++#endif
++
++#ifdef CONFIG_MACH_ROAD_S101
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ROAD_S101
++# endif
++# define machine_is_road_s101()       (machine_arch_type == MACH_TYPE_ROAD_S101)
++#else
++# define machine_is_road_s101()       (0)
++#endif
++
++#ifdef CONFIG_MACH_IQ_NEXTGEN_A
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_IQ_NEXTGEN_A
++# endif
++# define machine_is_iq_nextgen_a()    (machine_arch_type == MACH_TYPE_IQ_NEXTGEN_A)
++#else
++# define machine_is_iq_nextgen_a()    (0)
++#endif
++
++#ifdef CONFIG_MACH_IQ_NEXTGEN_B
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_IQ_NEXTGEN_B
++# endif
++# define machine_is_iq_nextgen_b()    (machine_arch_type == MACH_TYPE_IQ_NEXTGEN_B)
++#else
++# define machine_is_iq_nextgen_b()    (0)
++#endif
++
++#ifdef CONFIG_MACH_IQ_NEXTGEN_C
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_IQ_NEXTGEN_C
++# endif
++# define machine_is_iq_nextgen_c()    (machine_arch_type == MACH_TYPE_IQ_NEXTGEN_C)
++#else
++# define machine_is_iq_nextgen_c()    (0)
++#endif
++
++#ifdef CONFIG_MACH_IQ_NEXTGEN_D
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_IQ_NEXTGEN_D
++# endif
++# define machine_is_iq_nextgen_d()    (machine_arch_type == MACH_TYPE_IQ_NEXTGEN_D)
++#else
++# define machine_is_iq_nextgen_d()    (0)
++#endif
++
++#ifdef CONFIG_MACH_IQ_NEXTGEN_E
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_IQ_NEXTGEN_E
++# endif
++# define machine_is_iq_nextgen_e()    (machine_arch_type == MACH_TYPE_IQ_NEXTGEN_E)
++#else
++# define machine_is_iq_nextgen_e()    (0)
++#endif
++
++#ifdef CONFIG_MACH_MALLOW_AT91
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MALLOW_AT91
++# endif
++# define machine_is_mallow_at91()     (machine_arch_type == MACH_TYPE_MALLOW_AT91)
++#else
++# define machine_is_mallow_at91()     (0)
++#endif
++
++#ifdef CONFIG_MACH_CYBERTRACKER_I
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CYBERTRACKER_I
++# endif
++# define machine_is_cybertracker_i()  (machine_arch_type == MACH_TYPE_CYBERTRACKER_I)
++#else
++# define machine_is_cybertracker_i()  (0)
++#endif
++
++#ifdef CONFIG_MACH_GESBC931X
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_GESBC931X
++# endif
++# define machine_is_gesbc931x()       (machine_arch_type == MACH_TYPE_GESBC931X)
++#else
++# define machine_is_gesbc931x()       (0)
++#endif
++
++#ifdef CONFIG_MACH_CENTIPAD
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CENTIPAD
++# endif
++# define machine_is_centipad()        (machine_arch_type == MACH_TYPE_CENTIPAD)
++#else
++# define machine_is_centipad()        (0)
++#endif
++
++#ifdef CONFIG_MACH_ARMSOC
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ARMSOC
++# endif
++# define machine_is_armsoc()  (machine_arch_type == MACH_TYPE_ARMSOC)
++#else
++# define machine_is_armsoc()  (0)
++#endif
++
++#ifdef CONFIG_MACH_SE4200
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SE4200
++# endif
++# define machine_is_se4200()  (machine_arch_type == MACH_TYPE_SE4200)
++#else
++# define machine_is_se4200()  (0)
++#endif
++
++#ifdef CONFIG_MACH_EMS197A
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_EMS197A
++# endif
++# define machine_is_ems197a() (machine_arch_type == MACH_TYPE_EMS197A)
++#else
++# define machine_is_ems197a() (0)
++#endif
++
++#ifdef CONFIG_MACH_MICRO9
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MICRO9
++# endif
++# define machine_is_micro9()  (machine_arch_type == MACH_TYPE_MICRO9)
++#else
++# define machine_is_micro9()  (0)
++#endif
++
++#ifdef CONFIG_MACH_MICRO9L
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MICRO9L
++# endif
++# define machine_is_micro9l() (machine_arch_type == MACH_TYPE_MICRO9L)
++#else
++# define machine_is_micro9l() (0)
++#endif
++
++#ifdef CONFIG_MACH_UC5471DSP
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_UC5471DSP
++# endif
++# define machine_is_uc5471dsp()       (machine_arch_type == MACH_TYPE_UC5471DSP)
++#else
++# define machine_is_uc5471dsp()       (0)
++#endif
++
++#ifdef CONFIG_MACH_SJ5471ENG
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SJ5471ENG
++# endif
++# define machine_is_sj5471eng()       (machine_arch_type == MACH_TYPE_SJ5471ENG)
++#else
++# define machine_is_sj5471eng()       (0)
++#endif
++
++#ifdef CONFIG_MACH_CMPXA26X
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CMPXA26X
++# endif
++# define machine_is_none()    (machine_arch_type == MACH_TYPE_CMPXA26X)
++#else
++# define machine_is_none()    (0)
++#endif
++
++#ifdef CONFIG_MACH_NC
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NC
++# endif
++# define machine_is_nc1()     (machine_arch_type == MACH_TYPE_NC)
++#else
++# define machine_is_nc1()     (0)
++#endif
++
++#ifdef CONFIG_MACH_OMAP_PALMTE
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMAP_PALMTE
++# endif
++# define machine_is_omap_palmte()     (machine_arch_type == MACH_TYPE_OMAP_PALMTE)
++#else
++# define machine_is_omap_palmte()     (0)
++#endif
++
++#ifdef CONFIG_MACH_AJAX52X
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_AJAX52X
++# endif
++# define machine_is_ajax52x() (machine_arch_type == MACH_TYPE_AJAX52X)
++#else
++# define machine_is_ajax52x() (0)
++#endif
++
++#ifdef CONFIG_MACH_SIRIUSTAR
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SIRIUSTAR
++# endif
++# define machine_is_siriustar()       (machine_arch_type == MACH_TYPE_SIRIUSTAR)
++#else
++# define machine_is_siriustar()       (0)
++#endif
++
++#ifdef CONFIG_MACH_IODATA_HDLG
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_IODATA_HDLG
++# endif
++# define machine_is_iodata_hdlg()     (machine_arch_type == MACH_TYPE_IODATA_HDLG)
++#else
++# define machine_is_iodata_hdlg()     (0)
++#endif
++
++#ifdef CONFIG_MACH_AT91RM9200UTL
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_AT91RM9200UTL
++# endif
++# define machine_is_at91rm9200utl()   (machine_arch_type == MACH_TYPE_AT91RM9200UTL)
++#else
++# define machine_is_at91rm9200utl()   (0)
++#endif
++
++#ifdef CONFIG_MACH_BIOSAFE
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_BIOSAFE
++# endif
++# define machine_is_biosafe() (machine_arch_type == MACH_TYPE_BIOSAFE)
++#else
++# define machine_is_biosafe() (0)
++#endif
++
++#ifdef CONFIG_MACH_MP1000
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MP1000
++# endif
++# define machine_is_mp1000()  (machine_arch_type == MACH_TYPE_MP1000)
++#else
++# define machine_is_mp1000()  (0)
++#endif
++
++#ifdef CONFIG_MACH_PARSY
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PARSY
++# endif
++# define machine_is_parsy()   (machine_arch_type == MACH_TYPE_PARSY)
++#else
++# define machine_is_parsy()   (0)
++#endif
++
++#ifdef CONFIG_MACH_CCXP
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CCXP
++# endif
++# define machine_is_ccxp270() (machine_arch_type == MACH_TYPE_CCXP)
++#else
++# define machine_is_ccxp270() (0)
++#endif
++
++#ifdef CONFIG_MACH_OMAP_GSAMPLE
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMAP_GSAMPLE
++# endif
++# define machine_is_omap_gsample()    (machine_arch_type == MACH_TYPE_OMAP_GSAMPLE)
++#else
++# define machine_is_omap_gsample()    (0)
++#endif
++
++#ifdef CONFIG_MACH_REALVIEW_EB
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_REALVIEW_EB
++# endif
++# define machine_is_realview_eb()     (machine_arch_type == MACH_TYPE_REALVIEW_EB)
++#else
++# define machine_is_realview_eb()     (0)
++#endif
++
++#ifdef CONFIG_MACH_SAMOA
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SAMOA
++# endif
++# define machine_is_samoa()   (machine_arch_type == MACH_TYPE_SAMOA)
++#else
++# define machine_is_samoa()   (0)
++#endif
++
++#ifdef CONFIG_MACH_T3XSCALE
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_T3XSCALE
++# endif
++# define machine_is_t3xscale()        (machine_arch_type == MACH_TYPE_T3XSCALE)
++#else
++# define machine_is_t3xscale()        (0)
++#endif
++
++#ifdef CONFIG_MACH_I878
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_I878
++# endif
++# define machine_is_i878()    (machine_arch_type == MACH_TYPE_I878)
++#else
++# define machine_is_i878()    (0)
++#endif
++
++#ifdef CONFIG_MACH_BORZOI
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_BORZOI
++# endif
++# define machine_is_borzoi()  (machine_arch_type == MACH_TYPE_BORZOI)
++#else
++# define machine_is_borzoi()  (0)
++#endif
++
++#ifdef CONFIG_MACH_GECKO
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_GECKO
++# endif
++# define machine_is_gecko()   (machine_arch_type == MACH_TYPE_GECKO)
++#else
++# define machine_is_gecko()   (0)
++#endif
++
++#ifdef CONFIG_MACH_DS101
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_DS101
++# endif
++# define machine_is_ds101()   (machine_arch_type == MACH_TYPE_DS101)
++#else
++# define machine_is_ds101()   (0)
++#endif
++
++#ifdef CONFIG_MACH_OMAP_PALMTT2
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMAP_PALMTT2
++# endif
++# define machine_is_omap_palmtt2()    (machine_arch_type == MACH_TYPE_OMAP_PALMTT2)
++#else
++# define machine_is_omap_palmtt2()    (0)
++#endif
++
++#ifdef CONFIG_MACH_XSCALE_PALMLD
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_XSCALE_PALMLD
++# endif
++# define machine_is_xscale_palmld()   (machine_arch_type == MACH_TYPE_XSCALE_PALMLD)
++#else
++# define machine_is_xscale_palmld()   (0)
++#endif
++
++#ifdef CONFIG_MACH_CC9C
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CC9C
++# endif
++# define machine_is_cc9c()    (machine_arch_type == MACH_TYPE_CC9C)
++#else
++# define machine_is_cc9c()    (0)
++#endif
++
++#ifdef CONFIG_MACH_SBC1670
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SBC1670
++# endif
++# define machine_is_sbc1670() (machine_arch_type == MACH_TYPE_SBC1670)
++#else
++# define machine_is_sbc1670() (0)
++#endif
++
++#ifdef CONFIG_MACH_IXDP28X5
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_IXDP28X5
++# endif
++# define machine_is_ixdp28x5()        (machine_arch_type == MACH_TYPE_IXDP28X5)
++#else
++# define machine_is_ixdp28x5()        (0)
++#endif
++
++#ifdef CONFIG_MACH_OMAP_PALMTT
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMAP_PALMTT
++# endif
++# define machine_is_omap_palmtt()     (machine_arch_type == MACH_TYPE_OMAP_PALMTT)
++#else
++# define machine_is_omap_palmtt()     (0)
++#endif
++
++#ifdef CONFIG_MACH_ML696K
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ML696K
++# endif
++# define machine_is_ml696k()  (machine_arch_type == MACH_TYPE_ML696K)
++#else
++# define machine_is_ml696k()  (0)
++#endif
++
++#ifdef CONFIG_MACH_ARCOM_ZEUS
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ARCOM_ZEUS
++# endif
++# define machine_is_arcom_zeus()      (machine_arch_type == MACH_TYPE_ARCOM_ZEUS)
++#else
++# define machine_is_arcom_zeus()      (0)
++#endif
++
++#ifdef CONFIG_MACH_OSIRIS
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OSIRIS
++# endif
++# define machine_is_osiris()  (machine_arch_type == MACH_TYPE_OSIRIS)
++#else
++# define machine_is_osiris()  (0)
++#endif
++
++#ifdef CONFIG_MACH_MAESTRO
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MAESTRO
++# endif
++# define machine_is_maestro() (machine_arch_type == MACH_TYPE_MAESTRO)
++#else
++# define machine_is_maestro() (0)
++#endif
++
++#ifdef CONFIG_MACH_TUNGE2
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_TUNGE2
++# endif
++# define machine_is_tunge2()  (machine_arch_type == MACH_TYPE_TUNGE2)
++#else
++# define machine_is_tunge2()  (0)
++#endif
++
++#ifdef CONFIG_MACH_IXBBM
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_IXBBM
++# endif
++# define machine_is_ixbbm()   (machine_arch_type == MACH_TYPE_IXBBM)
++#else
++# define machine_is_ixbbm()   (0)
++#endif
++
++#ifdef CONFIG_MACH_MX27
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MX27
++# endif
++# define machine_is_mx27ads() (machine_arch_type == MACH_TYPE_MX27)
++#else
++# define machine_is_mx27ads() (0)
++#endif
++
++#ifdef CONFIG_MACH_AX8004
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_AX8004
++# endif
++# define machine_is_ax8004()  (machine_arch_type == MACH_TYPE_AX8004)
++#else
++# define machine_is_ax8004()  (0)
++#endif
++
++#ifdef CONFIG_MACH_AT91SAM9261EK
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_AT91SAM9261EK
++# endif
++# define machine_is_at91sam9261ek()   (machine_arch_type == MACH_TYPE_AT91SAM9261EK)
++#else
++# define machine_is_at91sam9261ek()   (0)
++#endif
++
++#ifdef CONFIG_MACH_LOFT
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_LOFT
++# endif
++# define machine_is_loft()    (machine_arch_type == MACH_TYPE_LOFT)
++#else
++# define machine_is_loft()    (0)
++#endif
++
++#ifdef CONFIG_MACH_MAGPIE
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MAGPIE
++# endif
++# define machine_is_magpie()  (machine_arch_type == MACH_TYPE_MAGPIE)
++#else
++# define machine_is_magpie()  (0)
++#endif
++
++#ifdef CONFIG_MACH_MX21
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MX21
++# endif
++# define machine_is_mx21ads() (machine_arch_type == MACH_TYPE_MX21)
++#else
++# define machine_is_mx21ads() (0)
++#endif
++
++#ifdef CONFIG_MACH_MB87M3400
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MB87M3400
++# endif
++# define machine_is_mb87m3400()       (machine_arch_type == MACH_TYPE_MB87M3400)
++#else
++# define machine_is_mb87m3400()       (0)
++#endif
++
++#ifdef CONFIG_MACH_MGUARD_DELTA
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MGUARD_DELTA
++# endif
++# define machine_is_mguard_delta()    (machine_arch_type == MACH_TYPE_MGUARD_DELTA)
++#else
++# define machine_is_mguard_delta()    (0)
++#endif
++
++#ifdef CONFIG_MACH_DAVINCI_DVDP
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_DAVINCI_DVDP
++# endif
++# define machine_is_davinci_dvdp()    (machine_arch_type == MACH_TYPE_DAVINCI_DVDP)
++#else
++# define machine_is_davinci_dvdp()    (0)
++#endif
++
++#ifdef CONFIG_MACH_HTCUNIVERSAL
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_HTCUNIVERSAL
++# endif
++# define machine_is_htcuniversal()    (machine_arch_type == MACH_TYPE_HTCUNIVERSAL)
++#else
++# define machine_is_htcuniversal()    (0)
++#endif
++
++#ifdef CONFIG_MACH_TPAD
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_TPAD
++# endif
++# define machine_is_tpad()    (machine_arch_type == MACH_TYPE_TPAD)
++#else
++# define machine_is_tpad()    (0)
++#endif
++
++#ifdef CONFIG_MACH_ROVERP3
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ROVERP3
++# endif
++# define machine_is_roverp3() (machine_arch_type == MACH_TYPE_ROVERP3)
++#else
++# define machine_is_roverp3() (0)
++#endif
++
++#ifdef CONFIG_MACH_JORNADA928
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_JORNADA928
++# endif
++# define machine_is_jornada928()      (machine_arch_type == MACH_TYPE_JORNADA928)
++#else
++# define machine_is_jornada928()      (0)
++#endif
++
++#ifdef CONFIG_MACH_MV88FXX81
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MV88FXX81
++# endif
++# define machine_is_mv88fxx81()       (machine_arch_type == MACH_TYPE_MV88FXX81)
++#else
++# define machine_is_mv88fxx81()       (0)
++#endif
++
++#ifdef CONFIG_MACH_STMP36XX
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_STMP36XX
++# endif
++# define machine_is_stmp36xx()        (machine_arch_type == MACH_TYPE_STMP36XX)
++#else
++# define machine_is_stmp36xx()        (0)
++#endif
++
++#ifdef CONFIG_MACH_SXNI79524
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SXNI79524
++# endif
++# define machine_is_sxni79524()       (machine_arch_type == MACH_TYPE_SXNI79524)
++#else
++# define machine_is_sxni79524()       (0)
++#endif
++
++#ifdef CONFIG_MACH_AMS_DELTA
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_AMS_DELTA
++# endif
++# define machine_is_ams_delta()       (machine_arch_type == MACH_TYPE_AMS_DELTA)
++#else
++# define machine_is_ams_delta()       (0)
++#endif
++
++#ifdef CONFIG_MACH_URANIUM
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_URANIUM
++# endif
++# define machine_is_uranium() (machine_arch_type == MACH_TYPE_URANIUM)
++#else
++# define machine_is_uranium() (0)
++#endif
++
++#ifdef CONFIG_MACH_UCON
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_UCON
++# endif
++# define machine_is_ucon()    (machine_arch_type == MACH_TYPE_UCON)
++#else
++# define machine_is_ucon()    (0)
++#endif
++
++#ifdef CONFIG_MACH_NAS100D
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NAS100D
++# endif
++# define machine_is_nas100d() (machine_arch_type == MACH_TYPE_NAS100D)
++#else
++# define machine_is_nas100d() (0)
++#endif
++
++#ifdef CONFIG_MACH_L083_1000
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_L083_1000
++# endif
++# define machine_is_l083()    (machine_arch_type == MACH_TYPE_L083_1000)
++#else
++# define machine_is_l083()    (0)
++#endif
++
++#ifdef CONFIG_MACH_EZX
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_EZX
++# endif
++# define machine_is_ezx()     (machine_arch_type == MACH_TYPE_EZX)
++#else
++# define machine_is_ezx()     (0)
++#endif
++
++#ifdef CONFIG_MACH_PNX5220
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PNX5220
++# endif
++# define machine_is_pnx5220() (machine_arch_type == MACH_TYPE_PNX5220)
++#else
++# define machine_is_pnx5220() (0)
++#endif
++
++#ifdef CONFIG_MACH_BUTTE
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_BUTTE
++# endif
++# define machine_is_butte()   (machine_arch_type == MACH_TYPE_BUTTE)
++#else
++# define machine_is_butte()   (0)
++#endif
++
++#ifdef CONFIG_MACH_SRM2
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SRM2
++# endif
++# define machine_is_srm2()    (machine_arch_type == MACH_TYPE_SRM2)
++#else
++# define machine_is_srm2()    (0)
++#endif
++
++#ifdef CONFIG_MACH_DSBR
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_DSBR
++# endif
++# define machine_is_dsbr()    (machine_arch_type == MACH_TYPE_DSBR)
++#else
++# define machine_is_dsbr()    (0)
++#endif
++
++#ifdef CONFIG_MACH_CRYSTALBALL
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CRYSTALBALL
++# endif
++# define machine_is_crystalball()     (machine_arch_type == MACH_TYPE_CRYSTALBALL)
++#else
++# define machine_is_crystalball()     (0)
++#endif
++
++#ifdef CONFIG_MACH_TINYPXA27X
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_TINYPXA27X
++# endif
++# define machine_is_tinypxa27x()      (machine_arch_type == MACH_TYPE_TINYPXA27X)
++#else
++# define machine_is_tinypxa27x()      (0)
++#endif
++
++#ifdef CONFIG_MACH_HERBIE
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_HERBIE
++# endif
++# define machine_is_herbie()  (machine_arch_type == MACH_TYPE_HERBIE)
++#else
++# define machine_is_herbie()  (0)
++#endif
++
++#ifdef CONFIG_MACH_MAGICIAN
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MAGICIAN
++# endif
++# define machine_is_magician()        (machine_arch_type == MACH_TYPE_MAGICIAN)
++#else
++# define machine_is_magician()        (0)
++#endif
++
++#ifdef CONFIG_MACH_CM4002
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CM4002
++# endif
++# define machine_is_cm4002()  (machine_arch_type == MACH_TYPE_CM4002)
++#else
++# define machine_is_cm4002()  (0)
++#endif
++
++#ifdef CONFIG_MACH_B4
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_B4
++# endif
++# define machine_is_b4()      (machine_arch_type == MACH_TYPE_B4)
++#else
++# define machine_is_b4()      (0)
++#endif
++
++#ifdef CONFIG_MACH_MAUI
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MAUI
++# endif
++# define machine_is_maui()    (machine_arch_type == MACH_TYPE_MAUI)
++#else
++# define machine_is_maui()    (0)
++#endif
++
++#ifdef CONFIG_MACH_CYBERTRACKER_G
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CYBERTRACKER_G
++# endif
++# define machine_is_cybertracker_g()  (machine_arch_type == MACH_TYPE_CYBERTRACKER_G)
++#else
++# define machine_is_cybertracker_g()  (0)
++#endif
++
++#ifdef CONFIG_MACH_NXDKN
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NXDKN
++# endif
++# define machine_is_nxdkn()   (machine_arch_type == MACH_TYPE_NXDKN)
++#else
++# define machine_is_nxdkn()   (0)
++#endif
++
++#ifdef CONFIG_MACH_MIO8390
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MIO8390
++# endif
++# define machine_is_mio8390() (machine_arch_type == MACH_TYPE_MIO8390)
++#else
++# define machine_is_mio8390() (0)
++#endif
++
++#ifdef CONFIG_MACH_OMI_BOARD
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMI_BOARD
++# endif
++# define machine_is_omi_board()       (machine_arch_type == MACH_TYPE_OMI_BOARD)
++#else
++# define machine_is_omi_board()       (0)
++#endif
++
++#ifdef CONFIG_MACH_MX21CIV
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MX21CIV
++# endif
++# define machine_is_mx21civ() (machine_arch_type == MACH_TYPE_MX21CIV)
++#else
++# define machine_is_mx21civ() (0)
++#endif
++
++#ifdef CONFIG_MACH_MAHI_CDAC
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MAHI_CDAC
++# endif
++# define machine_is_mahi_cdac()       (machine_arch_type == MACH_TYPE_MAHI_CDAC)
++#else
++# define machine_is_mahi_cdac()       (0)
++#endif
++
++#ifdef CONFIG_MACH_XSCALE_PALMTX
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_XSCALE_PALMTX
++# endif
++# define machine_is_xscale_palmtx()   (machine_arch_type == MACH_TYPE_XSCALE_PALMTX)
++#else
++# define machine_is_xscale_palmtx()   (0)
++#endif
++
++#ifdef CONFIG_MACH_S3C2413
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_S3C2413
++# endif
++# define machine_is_s3c2413() (machine_arch_type == MACH_TYPE_S3C2413)
++#else
++# define machine_is_s3c2413() (0)
++#endif
++
++#ifdef CONFIG_MACH_SAMSYS_EP0
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SAMSYS_EP0
++# endif
++# define machine_is_samsys_ep0()      (machine_arch_type == MACH_TYPE_SAMSYS_EP0)
++#else
++# define machine_is_samsys_ep0()      (0)
++#endif
++
++#ifdef CONFIG_MACH_WG302V1
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_WG302V1
++# endif
++# define machine_is_wg302v1() (machine_arch_type == MACH_TYPE_WG302V1)
++#else
++# define machine_is_wg302v1() (0)
++#endif
++
++#ifdef CONFIG_MACH_WG302V2
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_WG302V2
++# endif
++# define machine_is_wg302v2() (machine_arch_type == MACH_TYPE_WG302V2)
++#else
++# define machine_is_wg302v2() (0)
++#endif
++
++#ifdef CONFIG_MACH_EB42X
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_EB42X
++# endif
++# define machine_is_eb42x()   (machine_arch_type == MACH_TYPE_EB42X)
++#else
++# define machine_is_eb42x()   (0)
++#endif
++
++#ifdef CONFIG_MACH_IQ331ES
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_IQ331ES
++# endif
++# define machine_is_iq331es() (machine_arch_type == MACH_TYPE_IQ331ES)
++#else
++# define machine_is_iq331es() (0)
++#endif
++
++#ifdef CONFIG_MACH_COSYDSP
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_COSYDSP
++# endif
++# define machine_is_cosydsp() (machine_arch_type == MACH_TYPE_COSYDSP)
++#else
++# define machine_is_cosydsp() (0)
++#endif
++
++#ifdef CONFIG_MACH_UPLAT7D
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_UPLAT7D
++# endif
++# define machine_is_uplat7d_proto()   (machine_arch_type == MACH_TYPE_UPLAT7D)
++#else
++# define machine_is_uplat7d_proto()   (0)
++#endif
++
++#ifdef CONFIG_MACH_PTDAVINCI
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PTDAVINCI
++# endif
++# define machine_is_ptdavinci()       (machine_arch_type == MACH_TYPE_PTDAVINCI)
++#else
++# define machine_is_ptdavinci()       (0)
++#endif
++
++#ifdef CONFIG_MACH_MBUS
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MBUS
++# endif
++# define machine_is_mbus()    (machine_arch_type == MACH_TYPE_MBUS)
++#else
++# define machine_is_mbus()    (0)
++#endif
++
++#ifdef CONFIG_MACH_NADIA2VB
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NADIA2VB
++# endif
++# define machine_is_nadia2vb()        (machine_arch_type == MACH_TYPE_NADIA2VB)
++#else
++# define machine_is_nadia2vb()        (0)
++#endif
++
++#ifdef CONFIG_MACH_R1000
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_R1000
++# endif
++# define machine_is_r1000()   (machine_arch_type == MACH_TYPE_R1000)
++#else
++# define machine_is_r1000()   (0)
++#endif
++
++#ifdef CONFIG_MACH_HW90250
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_HW90250
++# endif
++# define machine_is_hw90250() (machine_arch_type == MACH_TYPE_HW90250)
++#else
++# define machine_is_hw90250() (0)
++#endif
++
++#ifdef CONFIG_MACH_OMAP_2430SDP
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMAP_2430SDP
++# endif
++# define machine_is_omap_2430sdp()    (machine_arch_type == MACH_TYPE_OMAP_2430SDP)
++#else
++# define machine_is_omap_2430sdp()    (0)
++#endif
++
++#ifdef CONFIG_MACH_DAVINCI_EVM
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_DAVINCI_EVM
++# endif
++# define machine_is_davinci_evm()     (machine_arch_type == MACH_TYPE_DAVINCI_EVM)
++#else
++# define machine_is_davinci_evm()     (0)
++#endif
++
++#ifdef CONFIG_MACH_OMAP_TORNADO
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMAP_TORNADO
++# endif
++# define machine_is_omap_tornado()    (machine_arch_type == MACH_TYPE_OMAP_TORNADO)
++#else
++# define machine_is_omap_tornado()    (0)
++#endif
++
++#ifdef CONFIG_MACH_OLOCREEK
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OLOCREEK
++# endif
++# define machine_is_olocreek()        (machine_arch_type == MACH_TYPE_OLOCREEK)
++#else
++# define machine_is_olocreek()        (0)
++#endif
++
++#ifdef CONFIG_MACH_PALMZ72
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PALMZ72
++# endif
++# define machine_is_palmz72() (machine_arch_type == MACH_TYPE_PALMZ72)
++#else
++# define machine_is_palmz72() (0)
++#endif
++
++#ifdef CONFIG_MACH_NXDB500
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NXDB500
++# endif
++# define machine_is_nxdb500() (machine_arch_type == MACH_TYPE_NXDB500)
++#else
++# define machine_is_nxdb500() (0)
++#endif
++
++#ifdef CONFIG_MACH_APF9328
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_APF9328
++# endif
++# define machine_is_apf9328() (machine_arch_type == MACH_TYPE_APF9328)
++#else
++# define machine_is_apf9328() (0)
++#endif
++
++#ifdef CONFIG_MACH_OMAP_WIPOQ
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMAP_WIPOQ
++# endif
++# define machine_is_omap_wipoq()      (machine_arch_type == MACH_TYPE_OMAP_WIPOQ)
++#else
++# define machine_is_omap_wipoq()      (0)
++#endif
++
++#ifdef CONFIG_MACH_OMAP_TWIP
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMAP_TWIP
++# endif
++# define machine_is_omap_twip()       (machine_arch_type == MACH_TYPE_OMAP_TWIP)
++#else
++# define machine_is_omap_twip()       (0)
++#endif
++
++#ifdef CONFIG_MACH_XSCALE_PALMTREO650
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_XSCALE_PALMTREO650
++# endif
++# define machine_is_xscale_treo650()  (machine_arch_type == MACH_TYPE_XSCALE_PALMTREO650)
++#else
++# define machine_is_xscale_treo650()  (0)
++#endif
++
++#ifdef CONFIG_MACH_ACUMEN
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ACUMEN
++# endif
++# define machine_is_acumen()  (machine_arch_type == MACH_TYPE_ACUMEN)
++#else
++# define machine_is_acumen()  (0)
++#endif
++
++#ifdef CONFIG_MACH_XP100
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_XP100
++# endif
++# define machine_is_xp100()   (machine_arch_type == MACH_TYPE_XP100)
++#else
++# define machine_is_xp100()   (0)
++#endif
++
++#ifdef CONFIG_MACH_FS2410
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_FS2410
++# endif
++# define machine_is_fs2410()  (machine_arch_type == MACH_TYPE_FS2410)
++#else
++# define machine_is_fs2410()  (0)
++#endif
++
++#ifdef CONFIG_MACH_PXA270_CERF
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PXA270_CERF
++# endif
++# define machine_is_pxa270_cerf()     (machine_arch_type == MACH_TYPE_PXA270_CERF)
++#else
++# define machine_is_pxa270_cerf()     (0)
++#endif
++
++#ifdef CONFIG_MACH_SQ2FTLPALM
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SQ2FTLPALM
++# endif
++# define machine_is_sq2ftlpalm()      (machine_arch_type == MACH_TYPE_SQ2FTLPALM)
++#else
++# define machine_is_sq2ftlpalm()      (0)
++#endif
++
++#ifdef CONFIG_MACH_BSEMSERVER
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_BSEMSERVER
++# endif
++# define machine_is_bsemserver()      (machine_arch_type == MACH_TYPE_BSEMSERVER)
++#else
++# define machine_is_bsemserver()      (0)
++#endif
++
++#ifdef CONFIG_MACH_NETCLIENT
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NETCLIENT
++# endif
++# define machine_is_netclient()       (machine_arch_type == MACH_TYPE_NETCLIENT)
++#else
++# define machine_is_netclient()       (0)
++#endif
++
++#ifdef CONFIG_MACH_XSCALE_PALMTT5
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_XSCALE_PALMTT5
++# endif
++# define machine_is_xscale_palmtt5()  (machine_arch_type == MACH_TYPE_XSCALE_PALMTT5)
++#else
++# define machine_is_xscale_palmtt5()  (0)
++#endif
++
++#ifdef CONFIG_MACH_OMAP_PALMTC
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMAP_PALMTC
++# endif
++# define machine_is_xscale_palmtc()   (machine_arch_type == MACH_TYPE_OMAP_PALMTC)
++#else
++# define machine_is_xscale_palmtc()   (0)
++#endif
++
++#ifdef CONFIG_MACH_OMAP_APOLLON
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMAP_APOLLON
++# endif
++# define machine_is_omap_apollon()    (machine_arch_type == MACH_TYPE_OMAP_APOLLON)
++#else
++# define machine_is_omap_apollon()    (0)
++#endif
++
++#ifdef CONFIG_MACH_ARGONLVEVB
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ARGONLVEVB
++# endif
++# define machine_is_mxc30030evb()     (machine_arch_type == MACH_TYPE_ARGONLVEVB)
++#else
++# define machine_is_mxc30030evb()     (0)
++#endif
++
++#ifdef CONFIG_MACH_REA_2D
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_REA_2D
++# endif
++# define machine_is_rea_2d()  (machine_arch_type == MACH_TYPE_REA_2D)
++#else
++# define machine_is_rea_2d()  (0)
++#endif
++
++#ifdef CONFIG_MACH_TI3E524
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_TI3E524
++# endif
++# define machine_is_eti3e524()        (machine_arch_type == MACH_TYPE_TI3E524)
++#else
++# define machine_is_eti3e524()        (0)
++#endif
++
++#ifdef CONFIG_MACH_ATEB9200
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ATEB9200
++# endif
++# define machine_is_ateb9200()        (machine_arch_type == MACH_TYPE_ATEB9200)
++#else
++# define machine_is_ateb9200()        (0)
++#endif
++
++#ifdef CONFIG_MACH_AUCKLAND
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_AUCKLAND
++# endif
++# define machine_is_auckland()        (machine_arch_type == MACH_TYPE_AUCKLAND)
++#else
++# define machine_is_auckland()        (0)
++#endif
++
++#ifdef CONFIG_MACH_AK3320M
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_AK3320M
++# endif
++# define machine_is_ak3220m() (machine_arch_type == MACH_TYPE_AK3320M)
++#else
++# define machine_is_ak3220m() (0)
++#endif
++
++#ifdef CONFIG_MACH_DURAMAX
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_DURAMAX
++# endif
++# define machine_is_duramax() (machine_arch_type == MACH_TYPE_DURAMAX)
++#else
++# define machine_is_duramax() (0)
++#endif
++
++#ifdef CONFIG_MACH_N35
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_N35
++# endif
++# define machine_is_n35()     (machine_arch_type == MACH_TYPE_N35)
++#else
++# define machine_is_n35()     (0)
++#endif
++
++#ifdef CONFIG_MACH_PRONGHORN
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PRONGHORN
++# endif
++# define machine_is_pronghorn()       (machine_arch_type == MACH_TYPE_PRONGHORN)
++#else
++# define machine_is_pronghorn()       (0)
++#endif
++
++#ifdef CONFIG_MACH_FUNDY
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_FUNDY
++# endif
++# define machine_is_fundy()   (machine_arch_type == MACH_TYPE_FUNDY)
++#else
++# define machine_is_fundy()   (0)
++#endif
++
++#ifdef CONFIG_MACH_LOGICPD_PXA270
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_LOGICPD_PXA270
++# endif
++# define machine_is_logicpd_pxa270()  (machine_arch_type == MACH_TYPE_LOGICPD_PXA270)
++#else
++# define machine_is_logicpd_pxa270()  (0)
++#endif
++
++#ifdef CONFIG_MACH_CPU777
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CPU777
++# endif
++# define machine_is_cpu777()  (machine_arch_type == MACH_TYPE_CPU777)
++#else
++# define machine_is_cpu777()  (0)
++#endif
++
++#ifdef CONFIG_MACH_SIMICON9201
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SIMICON9201
++# endif
++# define machine_is_simicon9201()     (machine_arch_type == MACH_TYPE_SIMICON9201)
++#else
++# define machine_is_simicon9201()     (0)
++#endif
++
++#ifdef CONFIG_MACH_LEAP2_HPM
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_LEAP2_HPM
++# endif
++# define machine_is_leap2_hpm()       (machine_arch_type == MACH_TYPE_LEAP2_HPM)
++#else
++# define machine_is_leap2_hpm()       (0)
++#endif
++
++#ifdef CONFIG_MACH_CM922TXA10
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CM922TXA10
++# endif
++# define machine_is_cm922txa10()      (machine_arch_type == MACH_TYPE_CM922TXA10)
++#else
++# define machine_is_cm922txa10()      (0)
++#endif
++
++#ifdef CONFIG_MACH_PXA
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PXA
++# endif
++# define machine_is_sandgate()        (machine_arch_type == MACH_TYPE_PXA)
++#else
++# define machine_is_sandgate()        (0)
++#endif
++
++#ifdef CONFIG_MACH_SANDGATE2
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SANDGATE2
++# endif
++# define machine_is_sandgate2()       (machine_arch_type == MACH_TYPE_SANDGATE2)
++#else
++# define machine_is_sandgate2()       (0)
++#endif
++
++#ifdef CONFIG_MACH_SANDGATE2G
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SANDGATE2G
++# endif
++# define machine_is_sandgate2g()      (machine_arch_type == MACH_TYPE_SANDGATE2G)
++#else
++# define machine_is_sandgate2g()      (0)
++#endif
++
++#ifdef CONFIG_MACH_SANDGATE2P
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SANDGATE2P
++# endif
++# define machine_is_sandgate2p()      (machine_arch_type == MACH_TYPE_SANDGATE2P)
++#else
++# define machine_is_sandgate2p()      (0)
++#endif
++
++#ifdef CONFIG_MACH_FRED_JACK
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_FRED_JACK
++# endif
++# define machine_is_fred_jack()       (machine_arch_type == MACH_TYPE_FRED_JACK)
++#else
++# define machine_is_fred_jack()       (0)
++#endif
++
++#ifdef CONFIG_MACH_TTG_COLOR1
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_TTG_COLOR1
++# endif
++# define machine_is_ttg_color1()      (machine_arch_type == MACH_TYPE_TTG_COLOR1)
++#else
++# define machine_is_ttg_color1()      (0)
++#endif
++
++#ifdef CONFIG_MACH_NXEB500HMI
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NXEB500HMI
++# endif
++# define machine_is_nxeb500hmi()      (machine_arch_type == MACH_TYPE_NXEB500HMI)
++#else
++# define machine_is_nxeb500hmi()      (0)
++#endif
++
++#ifdef CONFIG_MACH_NETDCU8
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NETDCU8
++# endif
++# define machine_is_netdcu8() (machine_arch_type == MACH_TYPE_NETDCU8)
++#else
++# define machine_is_netdcu8() (0)
++#endif
++
++#ifdef CONFIG_MACH_ML675050_CPU_BOA
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ML675050_CPU_BOA
++# endif
++# define machine_is_ml675050_cpu_boa()        (machine_arch_type == MACH_TYPE_ML675050_CPU_BOA)
++#else
++# define machine_is_ml675050_cpu_boa()        (0)
++#endif
++
++#ifdef CONFIG_MACH_NG_FVX538
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NG_FVX538
++# endif
++# define machine_is_ng_fvx538()       (machine_arch_type == MACH_TYPE_NG_FVX538)
++#else
++# define machine_is_ng_fvx538()       (0)
++#endif
++
++#ifdef CONFIG_MACH_NG_FVS338
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NG_FVS338
++# endif
++# define machine_is_ng_fvs338()       (machine_arch_type == MACH_TYPE_NG_FVS338)
++#else
++# define machine_is_ng_fvs338()       (0)
++#endif
++
++#ifdef CONFIG_MACH_PNX4103
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PNX4103
++# endif
++# define machine_is_pnx4103() (machine_arch_type == MACH_TYPE_PNX4103)
++#else
++# define machine_is_pnx4103() (0)
++#endif
++
++#ifdef CONFIG_MACH_HESDB
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_HESDB
++# endif
++# define machine_is_hesdb()   (machine_arch_type == MACH_TYPE_HESDB)
++#else
++# define machine_is_hesdb()   (0)
++#endif
++
++#ifdef CONFIG_MACH_XSILO
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_XSILO
++# endif
++# define machine_is_xsilo()   (machine_arch_type == MACH_TYPE_XSILO)
++#else
++# define machine_is_xsilo()   (0)
++#endif
++
++#ifdef CONFIG_MACH_ESPRESSO
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ESPRESSO
++# endif
++# define machine_is_espresso()        (machine_arch_type == MACH_TYPE_ESPRESSO)
++#else
++# define machine_is_espresso()        (0)
++#endif
++
++#ifdef CONFIG_MACH_EMLC
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_EMLC
++# endif
++# define machine_is_emlc()    (machine_arch_type == MACH_TYPE_EMLC)
++#else
++# define machine_is_emlc()    (0)
++#endif
++
++#ifdef CONFIG_MACH_SISTERON
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SISTERON
++# endif
++# define machine_is_sisteron()        (machine_arch_type == MACH_TYPE_SISTERON)
++#else
++# define machine_is_sisteron()        (0)
++#endif
++
++#ifdef CONFIG_MACH_RX1950
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_RX1950
++# endif
++# define machine_is_rx1950()  (machine_arch_type == MACH_TYPE_RX1950)
++#else
++# define machine_is_rx1950()  (0)
++#endif
++
++#ifdef CONFIG_MACH_TSC_VENUS
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_TSC_VENUS
++# endif
++# define machine_is_tsc_venus()       (machine_arch_type == MACH_TYPE_TSC_VENUS)
++#else
++# define machine_is_tsc_venus()       (0)
++#endif
++
++#ifdef CONFIG_MACH_DS101J
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_DS101J
++# endif
++# define machine_is_ds101j()  (machine_arch_type == MACH_TYPE_DS101J)
++#else
++# define machine_is_ds101j()  (0)
++#endif
++
++#ifdef CONFIG_MACH_MXC30030ADS
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MXC30030ADS
++# endif
++# define machine_is_mxc30030ads()     (machine_arch_type == MACH_TYPE_MXC30030ADS)
++#else
++# define machine_is_mxc30030ads()     (0)
++#endif
++
++#ifdef CONFIG_MACH_FUJITSU_WIMAXSOC
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_FUJITSU_WIMAXSOC
++# endif
++# define machine_is_fujitsu_wimaxsoc()        (machine_arch_type == MACH_TYPE_FUJITSU_WIMAXSOC)
++#else
++# define machine_is_fujitsu_wimaxsoc()        (0)
++#endif
++
++#ifdef CONFIG_MACH_DUALPCMODEM
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_DUALPCMODEM
++# endif
++# define machine_is_dualpcmodem()     (machine_arch_type == MACH_TYPE_DUALPCMODEM)
++#else
++# define machine_is_dualpcmodem()     (0)
++#endif
++
++#ifdef CONFIG_MACH_GESBC9312
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_GESBC9312
++# endif
++# define machine_is_gesbc9312()       (machine_arch_type == MACH_TYPE_GESBC9312)
++#else
++# define machine_is_gesbc9312()       (0)
++#endif
++
++#ifdef CONFIG_MACH_HTCAPACHE
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_HTCAPACHE
++# endif
++# define machine_is_htcapache()       (machine_arch_type == MACH_TYPE_HTCAPACHE)
++#else
++# define machine_is_htcapache()       (0)
++#endif
++
++#ifdef CONFIG_MACH_IXDP435
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_IXDP435
++# endif
++# define machine_is_ixdp435() (machine_arch_type == MACH_TYPE_IXDP435)
++#else
++# define machine_is_ixdp435() (0)
++#endif
++
++#ifdef CONFIG_MACH_CATPROVT100
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CATPROVT100
++# endif
++# define machine_is_catprovt100()     (machine_arch_type == MACH_TYPE_CATPROVT100)
++#else
++# define machine_is_catprovt100()     (0)
++#endif
++
++#ifdef CONFIG_MACH_PICOTUX1XX
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PICOTUX1XX
++# endif
++# define machine_is_picotux1xx()      (machine_arch_type == MACH_TYPE_PICOTUX1XX)
++#else
++# define machine_is_picotux1xx()      (0)
++#endif
++
++#ifdef CONFIG_MACH_PICOTUX2XX
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PICOTUX2XX
++# endif
++# define machine_is_picotux2xx()      (machine_arch_type == MACH_TYPE_PICOTUX2XX)
++#else
++# define machine_is_picotux2xx()      (0)
++#endif
++
++#ifdef CONFIG_MACH_DSMG600
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_DSMG600
++# endif
++# define machine_is_dsmg600() (machine_arch_type == MACH_TYPE_DSMG600)
++#else
++# define machine_is_dsmg600() (0)
++#endif
++
++#ifdef CONFIG_MACH_EMPC2
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_EMPC2
++# endif
++# define machine_is_empc2()   (machine_arch_type == MACH_TYPE_EMPC2)
++#else
++# define machine_is_empc2()   (0)
++#endif
++
++#ifdef CONFIG_MACH_VENTURA
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_VENTURA
++# endif
++# define machine_is_ventura() (machine_arch_type == MACH_TYPE_VENTURA)
++#else
++# define machine_is_ventura() (0)
++#endif
++
++#ifdef CONFIG_MACH_PHIDGET_SBC
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PHIDGET_SBC
++# endif
++# define machine_is_phidget_sbc()     (machine_arch_type == MACH_TYPE_PHIDGET_SBC)
++#else
++# define machine_is_phidget_sbc()     (0)
++#endif
++
++#ifdef CONFIG_MACH_IJ3K
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_IJ3K
++# endif
++# define machine_is_ij3k()    (machine_arch_type == MACH_TYPE_IJ3K)
++#else
++# define machine_is_ij3k()    (0)
++#endif
++
++#ifdef CONFIG_MACH_PISGAH
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PISGAH
++# endif
++# define machine_is_pisgah()  (machine_arch_type == MACH_TYPE_PISGAH)
++#else
++# define machine_is_pisgah()  (0)
++#endif
++
++#ifdef CONFIG_MACH_OMAP_FSAMPLE
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMAP_FSAMPLE
++# endif
++# define machine_is_omap_fsample()    (machine_arch_type == MACH_TYPE_OMAP_FSAMPLE)
++#else
++# define machine_is_omap_fsample()    (0)
++#endif
++
++#ifdef CONFIG_MACH_SG720
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SG720
++# endif
++# define machine_is_sg720()   (machine_arch_type == MACH_TYPE_SG720)
++#else
++# define machine_is_sg720()   (0)
++#endif
++
++#ifdef CONFIG_MACH_REDFOX
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_REDFOX
++# endif
++# define machine_is_redfox()  (machine_arch_type == MACH_TYPE_REDFOX)
++#else
++# define machine_is_redfox()  (0)
++#endif
++
++#ifdef CONFIG_MACH_MYSH_EP9315_1
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MYSH_EP9315_1
++# endif
++# define machine_is_mysh_ep9315_1()   (machine_arch_type == MACH_TYPE_MYSH_EP9315_1)
++#else
++# define machine_is_mysh_ep9315_1()   (0)
++#endif
++
++#ifdef CONFIG_MACH_TPF106
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_TPF106
++# endif
++# define machine_is_tpf106()  (machine_arch_type == MACH_TYPE_TPF106)
++#else
++# define machine_is_tpf106()  (0)
++#endif
++
++#ifdef CONFIG_MACH_AT91RM9200KG
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_AT91RM9200KG
++# endif
++# define machine_is_at91rm9200kg()    (machine_arch_type == MACH_TYPE_AT91RM9200KG)
++#else
++# define machine_is_at91rm9200kg()    (0)
++#endif
++
++#ifdef CONFIG_MACH_SLEDB
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SLEDB
++# endif
++# define machine_is_racemt2() (machine_arch_type == MACH_TYPE_SLEDB)
++#else
++# define machine_is_racemt2() (0)
++#endif
++
++#ifdef CONFIG_MACH_ONTRACK
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ONTRACK
++# endif
++# define machine_is_ontrack() (machine_arch_type == MACH_TYPE_ONTRACK)
++#else
++# define machine_is_ontrack() (0)
++#endif
++
++#ifdef CONFIG_MACH_PM1200
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PM1200
++# endif
++# define machine_is_pm1200()  (machine_arch_type == MACH_TYPE_PM1200)
++#else
++# define machine_is_pm1200()  (0)
++#endif
++
++#ifdef CONFIG_MACH_ESS24XXX
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ESS24XXX
++# endif
++# define machine_is_ess24562()        (machine_arch_type == MACH_TYPE_ESS24XXX)
++#else
++# define machine_is_ess24562()        (0)
++#endif
++
++#ifdef CONFIG_MACH_COREMP7
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_COREMP7
++# endif
++# define machine_is_coremp7() (machine_arch_type == MACH_TYPE_COREMP7)
++#else
++# define machine_is_coremp7() (0)
++#endif
++
++#ifdef CONFIG_MACH_NEXCODER_6446
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NEXCODER_6446
++# endif
++# define machine_is_nexcoder_6446()   (machine_arch_type == MACH_TYPE_NEXCODER_6446)
++#else
++# define machine_is_nexcoder_6446()   (0)
++#endif
++
++#ifdef CONFIG_MACH_STVC8380
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_STVC8380
++# endif
++# define machine_is_stvc8380()        (machine_arch_type == MACH_TYPE_STVC8380)
++#else
++# define machine_is_stvc8380()        (0)
++#endif
++
++#ifdef CONFIG_MACH_TEKLYNX
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_TEKLYNX
++# endif
++# define machine_is_teklynx() (machine_arch_type == MACH_TYPE_TEKLYNX)
++#else
++# define machine_is_teklynx() (0)
++#endif
++
++#ifdef CONFIG_MACH_CARBONADO
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CARBONADO
++# endif
++# define machine_is_carbonado()       (machine_arch_type == MACH_TYPE_CARBONADO)
++#else
++# define machine_is_carbonado()       (0)
++#endif
++
++#ifdef CONFIG_MACH_SYSMOS_MP730
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SYSMOS_MP730
++# endif
++# define machine_is_sysmos_mp730()    (machine_arch_type == MACH_TYPE_SYSMOS_MP730)
++#else
++# define machine_is_sysmos_mp730()    (0)
++#endif
++
++#ifdef CONFIG_MACH_SNAPPER_CL15
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SNAPPER_CL15
++# endif
++# define machine_is_snapper_cl15()    (machine_arch_type == MACH_TYPE_SNAPPER_CL15)
++#else
++# define machine_is_snapper_cl15()    (0)
++#endif
++
++#ifdef CONFIG_MACH_PGIGIM
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PGIGIM
++# endif
++# define machine_is_pgigim()  (machine_arch_type == MACH_TYPE_PGIGIM)
++#else
++# define machine_is_pgigim()  (0)
++#endif
++
++#ifdef CONFIG_MACH_PTX9160P2
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PTX9160P2
++# endif
++# define machine_is_ptx9160p2()       (machine_arch_type == MACH_TYPE_PTX9160P2)
++#else
++# define machine_is_ptx9160p2()       (0)
++#endif
++
++#ifdef CONFIG_MACH_DCORE1
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_DCORE1
++# endif
++# define machine_is_dcore1()  (machine_arch_type == MACH_TYPE_DCORE1)
++#else
++# define machine_is_dcore1()  (0)
++#endif
++
++#ifdef CONFIG_MACH_VICTORPXA
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_VICTORPXA
++# endif
++# define machine_is_victorpxa()       (machine_arch_type == MACH_TYPE_VICTORPXA)
++#else
++# define machine_is_victorpxa()       (0)
++#endif
++
++#ifdef CONFIG_MACH_MX2DTB
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MX2DTB
++# endif
++# define machine_is_mx2dtb()  (machine_arch_type == MACH_TYPE_MX2DTB)
++#else
++# define machine_is_mx2dtb()  (0)
++#endif
++
++#ifdef CONFIG_MACH_PXA_IREX_ER0100
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PXA_IREX_ER0100
++# endif
++# define machine_is_pxa_irex_er0100() (machine_arch_type == MACH_TYPE_PXA_IREX_ER0100)
++#else
++# define machine_is_pxa_irex_er0100() (0)
++#endif
++
++#ifdef CONFIG_MACH_OMAP_PALMZ71
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMAP_PALMZ71
++# endif
++# define machine_is_omap_palmz71()    (machine_arch_type == MACH_TYPE_OMAP_PALMZ71)
++#else
++# define machine_is_omap_palmz71()    (0)
++#endif
++
++#ifdef CONFIG_MACH_BARTEC_DEG
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_BARTEC_DEG
++# endif
++# define machine_is_bartec_deg()      (machine_arch_type == MACH_TYPE_BARTEC_DEG)
++#else
++# define machine_is_bartec_deg()      (0)
++#endif
++
++#ifdef CONFIG_MACH_HW50251
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_HW50251
++# endif
++# define machine_is_hw50251() (machine_arch_type == MACH_TYPE_HW50251)
++#else
++# define machine_is_hw50251() (0)
++#endif
++
++#ifdef CONFIG_MACH_IBOX
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_IBOX
++# endif
++# define machine_is_ibox()    (machine_arch_type == MACH_TYPE_IBOX)
++#else
++# define machine_is_ibox()    (0)
++#endif
++
++#ifdef CONFIG_MACH_ATLASLH7A404
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ATLASLH7A404
++# endif
++# define machine_is_atlaslh7a404()    (machine_arch_type == MACH_TYPE_ATLASLH7A404)
++#else
++# define machine_is_atlaslh7a404()    (0)
++#endif
++
++#ifdef CONFIG_MACH_PT2026
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PT2026
++# endif
++# define machine_is_pt2026()  (machine_arch_type == MACH_TYPE_PT2026)
++#else
++# define machine_is_pt2026()  (0)
++#endif
++
++#ifdef CONFIG_MACH_HTCALPINE
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_HTCALPINE
++# endif
++# define machine_is_htcalpine()       (machine_arch_type == MACH_TYPE_HTCALPINE)
++#else
++# define machine_is_htcalpine()       (0)
++#endif
++
++#ifdef CONFIG_MACH_BARTEC_VTU
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_BARTEC_VTU
++# endif
++# define machine_is_bartec_vtu()      (machine_arch_type == MACH_TYPE_BARTEC_VTU)
++#else
++# define machine_is_bartec_vtu()      (0)
++#endif
++
++#ifdef CONFIG_MACH_VCOREII
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_VCOREII
++# endif
++# define machine_is_vcoreii() (machine_arch_type == MACH_TYPE_VCOREII)
++#else
++# define machine_is_vcoreii() (0)
++#endif
++
++#ifdef CONFIG_MACH_PDNB3
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_PDNB3
++# endif
++# define machine_is_pdnb3()   (machine_arch_type == MACH_TYPE_PDNB3)
++#else
++# define machine_is_pdnb3()   (0)
++#endif
++
++#ifdef CONFIG_MACH_HTCBEETLES
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_HTCBEETLES
++# endif
++# define machine_is_htcbeetles()      (machine_arch_type == MACH_TYPE_HTCBEETLES)
++#else
++# define machine_is_htcbeetles()      (0)
++#endif
++
++#ifdef CONFIG_MACH_S3C6400
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_S3C6400
++# endif
++# define machine_is_s3c6400() (machine_arch_type == MACH_TYPE_S3C6400)
++#else
++# define machine_is_s3c6400() (0)
++#endif
++
++#ifdef CONFIG_MACH_S3C2443
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_S3C2443
++# endif
++# define machine_is_s3c2443() (machine_arch_type == MACH_TYPE_S3C2443)
++#else
++# define machine_is_s3c2443() (0)
++#endif
++
++#ifdef CONFIG_MACH_OMAP_LDK
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OMAP_LDK
++# endif
++# define machine_is_omap_ldk()        (machine_arch_type == MACH_TYPE_OMAP_LDK)
++#else
++# define machine_is_omap_ldk()        (0)
++#endif
++
++#ifdef CONFIG_MACH_SMDK2460
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SMDK2460
++# endif
++# define machine_is_smdk2460()        (machine_arch_type == MACH_TYPE_SMDK2460)
++#else
++# define machine_is_smdk2460()        (0)
++#endif
++
++#ifdef CONFIG_MACH_SMDK2440
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SMDK2440
++# endif
++# define machine_is_smdk2440()        (machine_arch_type == MACH_TYPE_SMDK2440)
++#else
++# define machine_is_smdk2440()        (0)
++#endif
++
++#ifdef CONFIG_MACH_SMDK2412
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SMDK2412
++# endif
++# define machine_is_smdk2412()        (machine_arch_type == MACH_TYPE_SMDK2412)
++#else
++# define machine_is_smdk2412()        (0)
++#endif
++
++#ifdef CONFIG_MACH_WEBBOX
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_WEBBOX
++# endif
++# define machine_is_webbox()  (machine_arch_type == MACH_TYPE_WEBBOX)
++#else
++# define machine_is_webbox()  (0)
++#endif
++
++#ifdef CONFIG_MACH_CWWNDP
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CWWNDP
++# endif
++# define machine_is_cwwndp()  (machine_arch_type == MACH_TYPE_CWWNDP)
++#else
++# define machine_is_cwwndp()  (0)
++#endif
++
++#ifdef CONFIG_MACH_DRAGON
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_DRAGON
++# endif
++# define machine_is_dragon()  (machine_arch_type == MACH_TYPE_DRAGON)
++#else
++# define machine_is_dragon()  (0)
++#endif
++
++#ifdef CONFIG_MACH_OPENDO_CPU_BOARD
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_OPENDO_CPU_BOARD
++# endif
++# define machine_is_opendo_cpu_board()        (machine_arch_type == MACH_TYPE_OPENDO_CPU_BOARD)
++#else
++# define machine_is_opendo_cpu_board()        (0)
++#endif
++
++#ifdef CONFIG_MACH_CCM2200
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CCM2200
++# endif
++# define machine_is_ccm2200() (machine_arch_type == MACH_TYPE_CCM2200)
++#else
++# define machine_is_ccm2200() (0)
++#endif
++
++#ifdef CONFIG_MACH_ETWARM
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_ETWARM
++# endif
++# define machine_is_etwarm()  (machine_arch_type == MACH_TYPE_ETWARM)
++#else
++# define machine_is_etwarm()  (0)
++#endif
++
++#ifdef CONFIG_MACH_M93030
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_M93030
++# endif
++# define machine_is_m93030()  (machine_arch_type == MACH_TYPE_M93030)
++#else
++# define machine_is_m93030()  (0)
++#endif
++
++#ifdef CONFIG_MACH_CC7U
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_CC7U
++# endif
++# define machine_is_cc7u()    (machine_arch_type == MACH_TYPE_CC7U)
++#else
++# define machine_is_cc7u()    (0)
++#endif
++
++#ifdef CONFIG_MACH_MTT_RANGER
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_MTT_RANGER
++# endif
++# define machine_is_mtt_ranger()      (machine_arch_type == MACH_TYPE_MTT_RANGER)
++#else
++# define machine_is_mtt_ranger()      (0)
++#endif
++
++#ifdef CONFIG_MACH_NEXUS
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NEXUS
++# endif
++# define machine_is_nexus()   (machine_arch_type == MACH_TYPE_NEXUS)
++#else
++# define machine_is_nexus()   (0)
++#endif
++
++#ifdef CONFIG_MACH_DESMAN
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_DESMAN
++# endif
++# define machine_is_desman()  (machine_arch_type == MACH_TYPE_DESMAN)
++#else
++# define machine_is_desman()  (0)
++#endif
++
++#ifdef CONFIG_MACH_BKDE303
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_BKDE303
++# endif
++# define machine_is_bkde303() (machine_arch_type == MACH_TYPE_BKDE303)
++#else
++# define machine_is_bkde303() (0)
++#endif
++
++#ifdef CONFIG_MACH_SMDK2413
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SMDK2413
++# endif
++# define machine_is_smdk2413()        (machine_arch_type == MACH_TYPE_SMDK2413)
++#else
++# define machine_is_smdk2413()        (0)
++#endif
++
++#ifdef CONFIG_MACH_AML_M7200
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_AML_M7200
++# endif
++# define machine_is_aml_m7200()       (machine_arch_type == MACH_TYPE_AML_M7200)
++#else
++# define machine_is_aml_m7200()       (0)
++#endif
++
++#ifdef CONFIG_MACH_AML_M5900
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_AML_M5900
++# endif
++# define machine_is_aml_m5900()       (machine_arch_type == MACH_TYPE_AML_M5900)
++#else
++# define machine_is_aml_m5900()       (0)
++#endif
++
++#ifdef CONFIG_MACH_SG640
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_SG640
++# endif
++# define machine_is_sg640()   (machine_arch_type == MACH_TYPE_SG640)
++#else
++# define machine_is_sg640()   (0)
++#endif
++
++#ifdef CONFIG_MACH_EDG79524
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_EDG79524
++# endif
++# define machine_is_edg79524()        (machine_arch_type == MACH_TYPE_EDG79524)
++#else
++# define machine_is_edg79524()        (0)
++#endif
++
++#ifdef CONFIG_MACH_AI2410
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_AI2410
++# endif
++# define machine_is_ai2410()  (machine_arch_type == MACH_TYPE_AI2410)
++#else
++# define machine_is_ai2410()  (0)
++#endif
++
++#ifdef CONFIG_MACH_IXP465
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_IXP465
++# endif
++# define machine_is_ixp465()  (machine_arch_type == MACH_TYPE_IXP465)
++#else
++# define machine_is_ixp465()  (0)
++#endif
++
++#ifdef CONFIG_MACH_BALLOON3
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_BALLOON3
++# endif
++# define machine_is_balloon3()        (machine_arch_type == MACH_TYPE_BALLOON3)
++#else
++# define machine_is_balloon3()        (0)
++#endif
++
++#ifdef CONFIG_MACH_QT2410
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_QT2410
++# endif
++# define machine_is_qt2410()  (machine_arch_type == MACH_TYPE_QT2410)
++#else
++# define machine_is_qt2410()  (0)
++#endif
++
++#ifdef CONFIG_MACH_NEO1973_GTA01
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NEO1973_GTA01
++# endif
++# define machine_is_neo1973_gta01()   (machine_arch_type == MACH_TYPE_NEO1973_GTA01)
++#else
++# define machine_is_neo1973_gta01()   (0)
++#endif
++
++#ifdef CONFIG_MACH_HXD8
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_HXD8
++# endif
++# define machine_is_hxd8()    (machine_arch_type == MACH_TYPE_HXD8)
++#else
++# define machine_is_neo8()    (0)
++#endif
++
++#ifdef CONFIG_MACH_NEO1973_GTA02
++# ifdef machine_arch_type
++#  undef machine_arch_type
++#  define machine_arch_type   __machine_arch_type
++# else
++#  define machine_arch_type   MACH_TYPE_NEO1973_GTA02
++# endif
++# define machine_is_neo1973_gta02()   (machine_arch_type == MACH_TYPE_NEO1973_GTA02)
++#else
++# define machine_is_neo1973_gta02()   (0)
++#endif
++
++
+ /*
+  * These have not yet been registered
+  */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-mokoversion.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-mokoversion.patch
new file mode 100644 (file)
index 0000000..a444341
--- /dev/null
@@ -0,0 +1,10 @@
+Index: u-boot/tools/setlocalversion
+===================================================================
+--- u-boot.orig/tools/setlocalversion  2007-03-26 14:42:58.000000000 +0200
++++ u-boot/tools/setlocalversion       2007-03-26 14:46:47.000000000 +0200
+@@ -20,3 +20,5 @@
+               printf '%s' -dirty
+       fi
+ fi
++
++printf '%s' -moko9
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-nand-markbad-reallybad.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-nand-markbad-reallybad.patch
new file mode 100644 (file)
index 0000000..d630889
--- /dev/null
@@ -0,0 +1,20 @@
+This patch makes sure that the 'nand markbad' command does not only mark a block
+'bad' in the bad-block table, but _also_ marks it bad in the OOB area.
+
+we need this to preserve the bad block status when re-creating the bad block table
+at some later point.
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+Index: u-boot/drivers/nand/nand_base.c
+===================================================================
+--- u-boot.orig/drivers/nand/nand_base.c       2007-03-01 12:47:31.000000000 +0100
++++ u-boot/drivers/nand/nand_base.c    2007-03-01 12:48:08.000000000 +0100
+@@ -481,7 +481,7 @@
+       /* Do we have a flash based bad block table ? */
+       if (this->options & NAND_USE_FLASH_BBT)
+-              return nand_update_bbt (mtd, ofs);
++              nand_update_bbt (mtd, ofs);
+       /* We write two bytes, so we dont have to mess with 16 bit access */
+       ofs += mtd->oobsize + (this->badblockpos & ~0x01);
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-neo1973-defaultenv.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-neo1973-defaultenv.patch
new file mode 100644 (file)
index 0000000..7e3aa4f
--- /dev/null
@@ -0,0 +1,31 @@
+Index: u-boot/include/configs/neo1973_gta01.h
+===================================================================
+--- u-boot.orig/include/configs/neo1973_gta01.h        2007-02-27 00:43:16.000000000 +0100
++++ u-boot/include/configs/neo1973_gta01.h     2007-02-27 00:47:49.000000000 +0100
+@@ -115,8 +115,8 @@
+ #include <cmd_confdefs.h>
+ #define CONFIG_BOOTDELAY      3
+-#define CONFIG_BOOTARGS       "rootfstype=jffs2 root=/dev/mtdblock4 console=ttySAC0,115200 console=tty0 loglevel=8"
+-#define CONFIG_BOOTCOMMAND    "nand read.e 0x32000000 0x34000 0x200000; bootm 0x32000000"
++#define CONFIG_BOOTARGS       ""
++#define CONFIG_BOOTCOMMAND    "setenv bootargs ${bootargs_base} ${mtdparts}; nand read.e 0x32000000 kernel; bootm 0x32000000"
+ #define CONFIG_DOS_PARTITION  1
+@@ -181,11 +181,14 @@
+ #define CONFIG_USBD_PRODUCTID_CDCACM  0x5119    /* CDC ACM */
+ #define CONFIG_USBD_MANUFACTURER      "OpenMoko, Inc"
+ #define CONFIG_USBD_PRODUCT_NAME      "Neo1973 Bootloader " U_BOOT_VERSION
+-#define CONFIG_EXTRA_ENV_SETTINGS     "usbtty=cdc_acm\0"
+ #define CONFIG_USBD_DFU                       1
+ #define CONFIG_USBD_DFU_XFER_SIZE     4096    /* 0x4000 */
+ #define CONFIG_USBD_DFU_INTERFACE     2
++#define CONFIG_EXTRA_ENV_SETTINGS                                     \
++      "usbtty=cdc_acm\0"                                              \
++      "bootargs_base=rootfstype=jffs2 root=/dev/mtdblock4 console=ttySAC0,115200 console=tty0 loglevel=8\0" \
++      ""
+ /*-----------------------------------------------------------------------
+  * Physical Memory Map
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-neo1973-resume.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-neo1973-resume.patch
new file mode 100644 (file)
index 0000000..19d9126
--- /dev/null
@@ -0,0 +1,113 @@
+Resume support for low-level uboot code, Version 5
+
+Signed-off-by: Ben Dooks <ben-linux@fluff.org>
+
+Index: u-boot/cpu/arm920t/start.S
+===================================================================
+--- u-boot.orig/cpu/arm920t/start.S    2007-02-28 03:51:24.000000000 +0100
++++ u-boot/cpu/arm920t/start.S 2007-03-01 02:43:47.000000000 +0100
+@@ -158,18 +158,68 @@
+       str     r1, [r0]
+ # endif
++      /* default FCLK is 202 MHz ! */
++#define LOCKTIME      0x4c000000
++#define UPLLCON               0x4c000008
++//#define MPLLCFG             ((0x90 << 12) + (0x2 << 4) + 0x2)
++#define MPLLCFG               ((0x90 << 12) + (0x7 << 4) + 0x0)
++#define UPLLCFG               ((0x78 << 12) + (0x2 << 4) + 0x3)
++      ldr     r0, =LOCKTIME
++      mov     r1, #0xffffff
++      str     r1, [r0]
++
++      ldr     r0, =UPLLCON
++      ldr     r1, =UPLLCFG
++      str     r1, [r0]
++
++      /* Page 7-19, seven nops between UPLL and MPLL */
++      nop
++      nop
++      nop
++      nop
++      nop
++      nop
++      nop
++
++      ldr     r1, =MPLLCFG
++      str     r1, [r0, #-4]           /* MPLLCON */
++
+       /* FCLK:HCLK:PCLK = 1:2:4 */
+-      /* default FCLK is 120 MHz ! */
+       ldr     r0, =CLKDIVN
+       mov     r1, #3
+       str     r1, [r0]
++
++#if 1
++      /* enable uart */
++      ldr     r0, =0x4c00000c         /* clkcon */
++      ldr     r1, =0x7fff0            /* all clocks on */
++      str     r1, [r0]
++
++      /* gpio UART0 init */
++      ldr     r0, =0x56000070
++      mov     r1, #0xaa
++      str     r1, [r0]
++
++      /* init uart */
++      ldr     r0, =0x50000000
++      mov     r1, #0x03
++      str     r1, [r0]
++      ldr     r1, =0x245
++      str     r1, [r0, #0x04]
++      mov     r1, #0x01
++      str     r1, [r0, #0x08]
++      mov     r1, #0x00
++      str     r1, [r0, #0x0c]
++      mov     r1, #0x1a
++      str     r1, [r0, #0x28]
++#endif
++
+ #endif        /* CONFIG_S3C2400 || CONFIG_S3C2410 */
+ #ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ #ifndef CONFIG_LL_INIT_NAND_ONLY
+       bl      cpu_init_crit
+ #endif
+-#endif
+ #ifndef CONFIG_SKIP_RELOCATE_UBOOT
+       adr     r0, _start              /* r0 <- current position of code   */
+@@ -202,9 +252,33 @@
+ #ifdef CONFIG_S3C2410_NAND_BOOT
+ nand_load:
++      /* take sdram out of power down */
++      ldr     r0, =0x56000080         /* misccr */
++      ldr     r1, [ r0 ]
++      bic     r1, r1, #(S3C2410_MISCCR_nEN_SCLK0 | S3C2410_MISCCR_nEN_SCLK1 | S3C2410_MISCCR_nEN_SCLKE)
++      str     r1, [ r0 ]
++
++      /* ensure signals stabalise */
++      mov     r1, #128
++1:    subs    r1, r1, #1
++      bpl     1b
++
+ #if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && defined(CONFIG_LL_INIT_NAND_ONLY)
+       bl      cpu_init_crit
+ #endif
++#if defined(CONFIG_S3C2410)
++      /* ensure some refresh has happened */
++      ldr     r1, =0xfffff
++1:    subs    r1, r1, #1
++      bpl     1b
++
++      /* test for resume */
++      ldr     r1, =0x560000B4         /* gstatus2 */
++      ldr     r0, [ r1 ]
++      tst     r0, #0x02               /* is this resume from power down */
++      ldrne   pc, [r1, #4]            /* gstatus3 */
++#endif /* CONFIG_S3C2410 */
++#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
+       /* mov  r10, lr */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-misccr-definitions.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-misccr-definitions.patch
new file mode 100644 (file)
index 0000000..6efe246
--- /dev/null
@@ -0,0 +1,45 @@
+Index: u-boot/include/s3c2410.h
+===================================================================
+--- u-boot.orig/include/s3c2410.h
++++ u-boot/include/s3c2410.h
+@@ -233,4 +233,40 @@ static inline S3C2410_SDI * S3C2410_GetB
+                rINTPND;\
+                }
+ /* Wait until rINTPND is changed for the case that the ISR is very short. */
++
++#define S3C2410_MISCCR_USBDEV     (0<<3)
++#define S3C2410_MISCCR_USBHOST            (1<<3)
++
++#define S3C2410_MISCCR_CLK0_MPLL    (0<<4)
++#define S3C2410_MISCCR_CLK0_UPLL    (1<<4)
++#define S3C2410_MISCCR_CLK0_FCLK    (2<<4)
++#define S3C2410_MISCCR_CLK0_HCLK    (3<<4)
++#define S3C2410_MISCCR_CLK0_PCLK    (4<<4)
++#define S3C2410_MISCCR_CLK0_DCLK0   (5<<4)
++#define S3C2410_MISCCR_CLK0_MASK    (7<<4)
++
++#define S3C2410_MISCCR_CLK1_MPLL    (0<<8)
++#define S3C2410_MISCCR_CLK1_UPLL    (1<<8)
++#define S3C2410_MISCCR_CLK1_FCLK    (2<<8)
++#define S3C2410_MISCCR_CLK1_HCLK    (3<<8)
++#define S3C2410_MISCCR_CLK1_PCLK    (4<<8)
++#define S3C2410_MISCCR_CLK1_DCLK1   (5<<8)
++#define S3C2410_MISCCR_CLK1_MASK    (7<<8)
++
++#define S3C2410_MISCCR_USBSUSPND0   (1<<12)
++#define S3C2410_MISCCR_USBSUSPND1   (1<<13)
++
++#define S3C2410_MISCCR_nRSTCON            (1<<16)
++
++#define S3C2410_MISCCR_nEN_SCLK0    (1<<17)
++#define S3C2410_MISCCR_nEN_SCLK1    (1<<18)
++#define S3C2410_MISCCR_nEN_SCLKE    (1<<19)
++#define S3C2410_MISCCR_SDSLEEP            (7<<17)
++
++#define S3C2410_CLKSLOW_UCLK_OFF      (1<<7)
++#define S3C2410_CLKSLOW_MPLL_OFF      (1<<5)
++#define S3C2410_CLKSLOW_SLOW          (1<<4)
++#define S3C2410_CLKSLOW_SLOWVAL(x)    (x)
++#define S3C2410_CLKSLOW_GET_SLOWVAL(x)        ((x) & 7)
++
+ #endif /*__S3C2410_H__*/
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-mmc.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-mmc.patch
new file mode 100644 (file)
index 0000000..b775bea
--- /dev/null
@@ -0,0 +1,818 @@
+This patch adds MMC/SD support to the S3C2410 SoC code in
+u-boot
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+
+Index: u-boot/cpu/arm920t/s3c24x0/Makefile
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/Makefile
++++ u-boot/cpu/arm920t/s3c24x0/Makefile
+@@ -26,7 +26,7 @@
+ LIB   = $(obj)lib$(SOC).a
+ COBJS = i2c.o interrupts.o serial.o speed.o \
+-        usb_ohci.o nand_read.o nand.o cmd_s3c2410.o
++        usb_ohci.o nand_read.o nand.o mmc.o cmd_s3c2410.o
+ SRCS  := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+ OBJS  := $(addprefix $(obj),$(SOBJS) $(COBJS))
+Index: u-boot/cpu/arm920t/s3c24x0/mmc.c
+===================================================================
+--- /dev/null
++++ u-boot/cpu/arm920t/s3c24x0/mmc.c
+@@ -0,0 +1,531 @@
++/*
++ * u-boot S3C2410 MMC/SD card driver
++ * (C) Copyright 2006 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * based on u-boot pxa MMC driver and linux/drivers/mmc/s3c2410mci.c
++ * (C) 2005-2005 Thomas Kleffel
++ *
++ * 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 <common.h>
++#include <mmc.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <s3c2410.h>
++#include <part.h>
++#include <fat.h>
++
++#ifdef CONFIG_MMC
++
++#define CONFIG_MMC_WIDE
++
++static S3C2410_SDI *sdi;
++
++static block_dev_desc_t mmc_dev;
++
++block_dev_desc_t * mmc_get_dev(int dev)
++{
++      return ((block_dev_desc_t *)&mmc_dev);
++}
++
++/*
++ * FIXME needs to read cid and csd info to determine block size
++ * and other parameters
++ */
++static uchar mmc_buf[MMC_BLOCK_SIZE];
++static mmc_csd_t mmc_csd;
++static int mmc_ready = 0;
++static int wide = 0;
++
++
++#define CMD_F_RESP    0x01
++#define CMD_F_RESP_LONG       0x02
++
++static u_int32_t *mmc_cmd(ushort cmd, ulong arg, ushort flags)
++{
++      static u_int32_t resp[5];
++
++      u_int32_t ccon, csta;
++      u_int32_t csta_rdy_bit = S3C2410_SDICMDSTAT_CMDSENT;
++
++      memset(resp, 0, sizeof(resp));
++
++      debug("mmc_cmd CMD%d arg=0x%08x flags=%x\n", cmd, arg, flags);
++
++      sdi->SDICSTA = 0xffffffff;
++      sdi->SDIDSTA = 0xffffffff;
++      sdi->SDIFSTA = 0xffffffff;
++
++      sdi->SDICARG = arg;
++
++      ccon = cmd & S3C2410_SDICMDCON_INDEX;
++      ccon |= S3C2410_SDICMDCON_SENDERHOST|S3C2410_SDICMDCON_CMDSTART;
++
++      if (flags & CMD_F_RESP) {
++              ccon |= S3C2410_SDICMDCON_WAITRSP;
++              csta_rdy_bit = S3C2410_SDICMDSTAT_RSPFIN; /* 1 << 9 */
++      }
++
++      if (flags & CMD_F_RESP_LONG)
++              ccon |= S3C2410_SDICMDCON_LONGRSP;
++
++      sdi->SDICCON = ccon;
++
++      while (1) {
++              csta = sdi->SDICSTA;
++              if (csta & csta_rdy_bit)
++                      break;
++              if (csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) {
++                      printf("===============> MMC CMD Timeout\n");
++                      sdi->SDICSTA |= S3C2410_SDICMDSTAT_CMDTIMEOUT;
++                      break;
++              }
++      }
++
++      debug("final MMC CMD status 0x%x\n", csta);
++
++      sdi->SDICSTA |= csta_rdy_bit;
++
++      if (flags & CMD_F_RESP) {
++              resp[0] = sdi->SDIRSP0;
++              resp[1] = sdi->SDIRSP1;
++              resp[2] = sdi->SDIRSP2;
++              resp[3] = sdi->SDIRSP3;
++      }
++
++      return resp;
++}
++
++#define FIFO_FILL(host) ((host->SDIFSTA & S3C2410_SDIFSTA_COUNTMASK) >> 2)
++
++static int mmc_block_read(uchar *dst, ulong src, ulong len)
++{
++      u_int32_t dcon, fifo;
++      u_int32_t *dst_u32 = (u_int32_t *)dst;
++      u_int32_t *resp;
++
++      if (len == 0)
++              return 0;
++
++      debug("mmc_block_rd dst %lx src %lx len %d\n", (ulong)dst, src, len);
++
++      /* set block len */
++      resp = mmc_cmd(MMC_CMD_SET_BLOCKLEN, len, CMD_F_RESP);
++      sdi->SDIBSIZE = len;
++
++      //sdi->SDIPRE = 0xff;
++
++      /* setup data */
++      dcon = (len >> 9) & S3C2410_SDIDCON_BLKNUM;
++      dcon |= S3C2410_SDIDCON_BLOCKMODE;
++      dcon |= S3C2410_SDIDCON_RXAFTERCMD|S3C2410_SDIDCON_XFER_RXSTART;
++      if (wide)
++              dcon |= S3C2410_SDIDCON_WIDEBUS;
++      sdi->SDIDCON = dcon;
++
++      /* send read command */
++      resp = mmc_cmd(MMC_CMD_READ_BLOCK, src, CMD_F_RESP);
++
++      while (len > 0) {
++              u_int32_t sdidsta = sdi->SDIDSTA;
++              fifo = FIFO_FILL(sdi);
++              if (sdidsta & (S3C2410_SDIDSTA_FIFOFAIL|
++                              S3C2410_SDIDSTA_CRCFAIL|
++                              S3C2410_SDIDSTA_RXCRCFAIL|
++                              S3C2410_SDIDSTA_DATATIMEOUT)) {
++                      printf("mmc_block_read: err SDIDSTA=0x%08x\n", sdidsta);
++                      return -EIO;
++              }
++
++              while (fifo--) {
++                      //debug("dst_u32 = 0x%08x\n", dst_u32);
++                      *(dst_u32++) = sdi->SDIDAT;
++                      if (len >= 4)
++                              len -= 4;
++                      else {
++                              len = 0;
++                              break;
++                      }
++              }
++      }
++
++      debug("waiting for SDIDSTA  (currently 0x%08x\n", sdi->SDIDSTA);
++      while (!(sdi->SDIDSTA & (1 << 4))) {}
++      debug("done waiting for SDIDSTA (currently 0x%08x\n", sdi->SDIDSTA);
++
++      sdi->SDIDCON = 0;
++
++      if (!(sdi->SDIDSTA & S3C2410_SDIDSTA_XFERFINISH))
++              debug("mmc_block_read; transfer not finished!\n");
++
++      return 0;
++}
++
++static int mmc_block_write(ulong dst, uchar *src, int len)
++{
++      printf("MMC block write not yet supported on S3C2410!\n");
++      return -1;
++}
++
++
++int mmc_read(ulong src, uchar *dst, int size)
++{
++      ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
++      ulong mmc_block_size, mmc_block_address;
++
++      if (size == 0)
++              return 0;
++
++      if (!mmc_ready) {
++              printf("Please initialize the MMC first\n");
++              return -1;
++      }
++
++      mmc_block_size = MMC_BLOCK_SIZE;
++      mmc_block_address = ~(mmc_block_size - 1);
++
++      src -= CFG_MMC_BASE;
++      end = src + size;
++      part_start = ~mmc_block_address & src;
++      part_end = ~mmc_block_address & end;
++      aligned_start = mmc_block_address & src;
++      aligned_end = mmc_block_address & end;
++
++      /* all block aligned accesses */
++      debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
++      src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
++      if (part_start) {
++              part_len = mmc_block_size - part_start;
++              debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
++              src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
++              if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
++                      return -1;
++
++              memcpy(dst, mmc_buf+part_start, part_len);
++              dst += part_len;
++              src += part_len;
++      }
++      debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
++      src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
++      for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
++              debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
++              src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
++              if ((mmc_block_read((uchar *)(dst), src, mmc_block_size)) < 0)
++                      return -1;
++      }
++      debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
++      src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
++      if (part_end && src < end) {
++              debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
++              src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
++              if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
++                      return -1;
++
++              memcpy(dst, mmc_buf, part_end);
++      }
++      return 0;
++}
++
++int mmc_write(uchar *src, ulong dst, int size)
++{
++      ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
++      ulong mmc_block_size, mmc_block_address;
++
++      if (size == 0)
++              return 0;
++
++      if (!mmc_ready) {
++              printf("Please initialize the MMC first\n");
++              return -1;
++      }
++
++      mmc_block_size = MMC_BLOCK_SIZE;
++      mmc_block_address = ~(mmc_block_size - 1);
++
++      dst -= CFG_MMC_BASE;
++      end = dst + size;
++      part_start = ~mmc_block_address & dst;
++      part_end = ~mmc_block_address & end;
++      aligned_start = mmc_block_address & dst;
++      aligned_end = mmc_block_address & end;
++
++      /* all block aligned accesses */
++      debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
++      src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
++      if (part_start) {
++              part_len = mmc_block_size - part_start;
++              debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
++              (ulong)src, dst, end, part_start, part_end, aligned_start, aligned_end);
++              if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
++                      return -1;
++
++              memcpy(mmc_buf+part_start, src, part_len);
++              if ((mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) < 0)
++                      return -1;
++
++              dst += part_len;
++              src += part_len;
++      }
++      debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
++      src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
++      for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
++              debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
++              src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
++              if ((mmc_block_write(dst, (uchar *)src, mmc_block_size)) < 0)
++                      return -1;
++
++      }
++      debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
++      src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
++      if (part_end && dst < end) {
++              debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
++              src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
++              if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
++                      return -1;
++
++              memcpy(mmc_buf, src, part_end);
++              if ((mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0)
++                      return -1;
++
++      }
++      return 0;
++}
++
++ulong mmc_bread(int dev_num, ulong blknr, ulong blkcnt, void *dst)
++{
++      int mmc_block_size = MMC_BLOCK_SIZE;
++      ulong src = blknr * mmc_block_size + CFG_MMC_BASE;
++
++      mmc_read(src, dst, blkcnt*mmc_block_size);
++      return blkcnt;
++}
++
++/* MMC_DEFAULT_RCA should probably be just 1, but this may break other code
++   that expects it to be shifted. */
++static u_int16_t rca = MMC_DEFAULT_RCA >> 16;
++
++static u_int32_t mmc_size(const struct mmc_csd *csd)
++{
++      u_int32_t block_len, mult, blocknr;
++
++      block_len = csd->read_bl_len << 12;
++      mult = csd->c_size_mult1 << 8;
++      blocknr = (csd->c_size+1) * mult;
++
++      return blocknr * block_len;
++}
++
++struct sd_cid {
++      char            pnm_0;  /* product name */
++      char            oid_1;  /* OEM/application ID */
++      char            oid_0;
++      uint8_t         mid;    /* manufacturer ID */
++      char            pnm_4;
++      char            pnm_3;
++      char            pnm_2;
++      char            pnm_1;
++      uint8_t         psn_2;  /* product serial number */
++      uint8_t         psn_1;
++      uint8_t         psn_0;  /* MSB */
++      uint8_t         prv;    /* product revision */
++      uint8_t         crc;    /* CRC7 checksum, b0 is unused and set to 1 */
++      uint8_t         mdt_1;  /* manufacturing date, LSB, RRRRyyyy yyyymmmm */
++      uint8_t         mdt_0;  /* MSB */
++      uint8_t         psn_3;  /* LSB */
++};
++
++static void print_mmc_cid(mmc_cid_t *cid)
++{
++      printf("MMC found. Card desciption is:\n");
++      printf("Manufacturer ID = %02x%02x%02x\n",
++              cid->id[0], cid->id[1], cid->id[2]);
++      printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev);
++      cid->hwrev = cid->fwrev = 0;    /* null terminate string */
++      printf("Product Name = %s\n",cid->name);
++      printf("Serial Number = %02x%02x%02x\n",
++              cid->sn[0], cid->sn[1], cid->sn[2]);
++      printf("Month = %d\n",cid->month);
++      printf("Year = %d\n",1997 + cid->year);
++}
++
++static void print_sd_cid(const struct sd_cid *cid)
++{
++      printf("Manufacturer:       0x%02x, OEM \"%c%c\"\n",
++          cid->mid, cid->oid_0, cid->oid_1);
++      printf("Product name:       \"%c%c%c%c%c\", revision %d.%d\n",
++          cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3, cid->pnm_4,
++          cid->prv >> 4, cid->prv & 15);
++      printf("Serial number:      %u\n",
++          cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 |
++          cid->psn_3);
++      printf("Manufacturing date: %d/%d\n",
++          cid->mdt_1 & 15,
++          2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4));
++      printf("CRC:                0x%02x, b0 = %d\n",
++          cid->crc >> 1, cid->crc & 1);
++}
++
++int mmc_init(int verbose)
++{
++      int retries, rc = -ENODEV;
++      int is_sd = 0;
++      u_int32_t *resp;
++      S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
++
++      sdi = S3C2410_GetBase_SDI();
++
++      debug("mmc_init(PCLK=%u)\n", get_PCLK());
++
++      clk_power->CLKCON |= (1 << 9);
++
++      /* S3C2410 has some bug that prevents reliable operation at higher speed */
++      //sdi->SDIPRE = 0x3e;  /* SDCLK = PCLK/2 / (SDIPRE+1) = 396kHz */
++      sdi->SDIPRE = 0x02;  /* SDCLK = PCLK/2 / (SDIPRE+1) = 396kHz */
++      sdi->SDIBSIZE = 512;
++      sdi->SDIDTIMER = 0xffff;
++      sdi->SDIIMSK = 0x0;
++      sdi->SDICON = S3C2410_SDICON_FIFORESET|S3C2440_SDICON_MMCCLOCK;
++      udelay(125000); /* FIXME: 74 SDCLK cycles */
++
++      mmc_csd.c_size = 0;
++
++      /* reset */
++      retries = 10;
++      resp = mmc_cmd(MMC_CMD_RESET, 0, 0);
++
++      printf("trying to detect SD Card...\n");
++      while (retries--) {
++              udelay(100000);
++              resp = mmc_cmd(55, 0x00000000, CMD_F_RESP);
++              resp = mmc_cmd(41, 0x00300000, CMD_F_RESP);
++
++              if (resp[0] & (1 << 31)) {
++                      is_sd = 1;
++                      break;
++              }
++      }
++
++      if (retries == 0 && !is_sd) {
++              retries = 10;
++              printf("failed to detect SD Card, trying MMC\n");
++              resp = mmc_cmd(MMC_CMD_SEND_OP_COND, 0x00ffc000, CMD_F_RESP);
++              while (retries-- && resp && !(resp[4] & 0x80)) {
++                      debug("resp %x %x\n", resp[0], resp[1]);
++                      udelay(50);
++                      resp = mmc_cmd(1, 0x00ffff00, CMD_F_RESP);
++              }
++      }
++
++      /* try to get card id */
++      resp = mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, CMD_F_RESP|CMD_F_RESP_LONG);
++      if (resp) {
++              if (!is_sd) {
++                      /* TODO configure mmc driver depending on card
++                         attributes */
++                      mmc_cid_t *cid = (mmc_cid_t *)resp;
++
++                      if (verbose)
++                              print_mmc_cid(cid);
++                      sprintf((char *) mmc_dev.vendor,
++                              "Man %02x%02x%02x Snr %02x%02x%02x",
++                              cid->id[0], cid->id[1], cid->id[2],
++                              cid->sn[0], cid->sn[1], cid->sn[2]);
++                      sprintf((char *) mmc_dev.product,"%s",cid->name);
++                      sprintf((char *) mmc_dev.revision,"%x %x",
++                              cid->hwrev, cid->fwrev);
++              }
++              else {
++                      struct sd_cid *cid = (struct sd_cid *) resp;
++
++                      if (verbose)
++                              print_sd_cid(cid);
++                      sprintf((char *) mmc_dev.vendor,
++                          "Man %02 OEM %c%c \"%c%c%c%c%c\"",
++                          cid->mid, cid->oid_0, cid->oid_1,
++                          cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3,
++                          cid->pnm_4);
++                      sprintf((char *) mmc_dev.product, "%d",
++                          cid->psn_0 << 24 | cid->psn_1 << 16 |
++                          cid->psn_2 << 8 | cid->psn_3);
++                      sprintf((char *) mmc_dev.revision, "%d.%d",
++                          cid->prv >> 4, cid->prv & 15);
++              }
++
++              /* fill in device description */
++              mmc_dev.if_type = IF_TYPE_MMC;
++              mmc_dev.part_type = PART_TYPE_DOS;
++              mmc_dev.dev = 0;
++              mmc_dev.lun = 0;
++              mmc_dev.type = 0;
++              /* FIXME fill in the correct size (is set to 32MByte) */
++              mmc_dev.blksz = 512;
++              mmc_dev.lba = 0x10000;
++              mmc_dev.removable = 0;
++              mmc_dev.block_read = mmc_bread;
++
++              /* MMC exists, get CSD too */
++              resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, CMD_F_RESP);
++              if (is_sd)
++                      rca = resp[0] >> 16;
++
++              resp = mmc_cmd(MMC_CMD_SEND_CSD, rca<<16, CMD_F_RESP|CMD_F_RESP_LONG);
++              if (resp) {
++                      mmc_csd_t *csd = (mmc_csd_t *)resp;
++                      memcpy(&mmc_csd, csd, sizeof(csd));
++                      rc = 0;
++                      mmc_ready = 1;
++                      /* FIXME add verbose printout for csd */
++                      printf("READ_BL_LEN=%u, C_SIZE_MULT=%u, C_SIZE=%u\n",
++                              csd->read_bl_len, csd->c_size_mult1, csd->c_size);
++                      printf("size = %u\n", mmc_size(csd));
++              }
++      }
++
++      resp = mmc_cmd(MMC_CMD_SELECT_CARD, rca<<16, CMD_F_RESP);
++
++#ifdef CONFIG_MMC_WIDE
++      if (is_sd) {
++              resp = mmc_cmd(55, rca<<16, CMD_F_RESP);
++              resp = mmc_cmd(6, 0x02, CMD_F_RESP);
++              wide = 1;
++      }
++#endif
++
++      fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
++
++      return rc;
++}
++
++int
++mmc_ident(block_dev_desc_t *dev)
++{
++      return 0;
++}
++
++int
++mmc2info(ulong addr)
++{
++      /* FIXME hard codes to 32 MB device */
++      if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000)
++              return 1;
++
++      return 0;
++}
++
++#endif        /* CONFIG_MMC */
+Index: u-boot/include/asm-arm/arch-s3c24x0/mmc.h
+===================================================================
+--- /dev/null
++++ u-boot/include/asm-arm/arch-s3c24x0/mmc.h
+@@ -0,0 +1,112 @@
++/*
++ *  linux/drivers/mmc/mmc_pxa.h
++ *
++ *  Author: Vladimir Shebordaev, Igor Oblakov
++ *  Copyright:  MontaVista Software Inc.
++ *
++ *  $Id: mmc_pxa.h,v 0.3.1.6 2002/09/25 19:25:48 ted Exp ted $
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License version 2 as
++ *  published by the Free Software Foundation.
++ */
++#ifndef __MMC_PXA_P_H__
++#define __MMC_PXA_P_H__
++
++#include <asm/arch/regs-sdi.h>
++
++#define MMC_DEFAULT_RCA                       (1<<16)
++
++#define MMC_BLOCK_SIZE                        512
++#define MMC_CMD_RESET                 0
++#define MMC_CMD_SEND_OP_COND          1
++#define MMC_CMD_ALL_SEND_CID          2
++#define MMC_CMD_SET_RCA                       3
++#define MMC_CMD_SELECT_CARD           7
++#define MMC_CMD_SEND_CSD              9
++#define MMC_CMD_SEND_CID              10
++#define MMC_CMD_SEND_STATUS           13
++#define MMC_CMD_SET_BLOCKLEN          16
++#define MMC_CMD_READ_BLOCK            17
++#define MMC_CMD_RD_BLK_MULTI          18
++#define MMC_CMD_WRITE_BLOCK           24
++
++#define MMC_MAX_BLOCK_SIZE            512
++
++#define MMC_R1_IDLE_STATE             0x01
++#define MMC_R1_ERASE_STATE            0x02
++#define MMC_R1_ILLEGAL_CMD            0x04
++#define MMC_R1_COM_CRC_ERR            0x08
++#define MMC_R1_ERASE_SEQ_ERR          0x01
++#define MMC_R1_ADDR_ERR                       0x02
++#define MMC_R1_PARAM_ERR              0x04
++
++#define MMC_R1B_WP_ERASE_SKIP         0x0002
++#define MMC_R1B_ERR                   0x0004
++#define MMC_R1B_CC_ERR                        0x0008
++#define MMC_R1B_CARD_ECC_ERR          0x0010
++#define MMC_R1B_WP_VIOLATION          0x0020
++#define MMC_R1B_ERASE_PARAM           0x0040
++#define MMC_R1B_OOR                   0x0080
++#define MMC_R1B_IDLE_STATE            0x0100
++#define MMC_R1B_ERASE_RESET           0x0200
++#define MMC_R1B_ILLEGAL_CMD           0x0400
++#define MMC_R1B_COM_CRC_ERR           0x0800
++#define MMC_R1B_ERASE_SEQ_ERR         0x1000
++#define MMC_R1B_ADDR_ERR              0x2000
++#define MMC_R1B_PARAM_ERR             0x4000
++
++typedef struct mmc_cid
++{
++      /* FIXME: BYTE_ORDER */
++      uchar   year:4,
++              month:4;
++      uchar   sn[3];
++      uchar   fwrev:4,
++              hwrev:4;
++      uchar   name[6];
++      uchar   id[3];
++} mmc_cid_t;
++
++typedef struct mmc_csd
++{
++      uchar   ecc:2,
++              file_format:2,
++              tmp_write_protect:1,
++              perm_write_protect:1,
++              copy:1,
++              file_format_grp:1;
++      uint64_t content_prot_app:1,
++              rsvd3:4,
++              write_bl_partial:1,
++              write_bl_len:4,
++              r2w_factor:3,
++              default_ecc:2,
++              wp_grp_enable:1,
++              wp_grp_size:5,
++              erase_grp_mult:5,
++              erase_grp_size:5,
++              c_size_mult1:3,
++              vdd_w_curr_max:3,
++              vdd_w_curr_min:3,
++              vdd_r_curr_max:3,
++              vdd_r_curr_min:3,
++              c_size:12,
++              rsvd2:2,
++              dsr_imp:1,
++              read_blk_misalign:1,
++              write_blk_misalign:1,
++              read_bl_partial:1;
++
++      ushort  read_bl_len:4,
++              ccc:12;
++      uchar   tran_speed;
++      uchar   nsac;
++      uchar   taac;
++      uchar   rsvd1:2,
++              spec_vers:4,
++              csd_structure:2;
++} mmc_csd_t;
++
++
++#endif /* __MMC_PXA_P_H__ */
+Index: u-boot/include/asm-arm/arch-s3c24x0/regs-sdi.h
+===================================================================
+--- /dev/null
++++ u-boot/include/asm-arm/arch-s3c24x0/regs-sdi.h
+@@ -0,0 +1,110 @@
++/* linux/include/asm/arch-s3c2410/regs-sdi.h
++ *
++ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
++ *                  http://www.simtec.co.uk/products/SWLINUX/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * S3C2410 MMC/SDIO register definitions
++ *
++ *  Changelog:
++ *    18-Aug-2004 Ben Dooks      Created initial file
++ *    29-Nov-2004 Koen Martens   Added some missing defines, fixed duplicates
++ *    29-Nov-2004 Ben Dooks    Updated Koen's patch
++*/
++
++#ifndef __ASM_ARM_REGS_SDI
++#define __ASM_ARM_REGS_SDI "regs-sdi.h"
++
++#define S3C2440_SDICON_SDRESET        (1<<8)
++#define S3C2440_SDICON_MMCCLOCK       (1<<5)
++#define S3C2410_SDICON_BYTEORDER      (1<<4)
++#define S3C2410_SDICON_SDIOIRQ        (1<<3)
++#define S3C2410_SDICON_RWAITEN        (1<<2)
++#define S3C2410_SDICON_FIFORESET      (1<<1)
++#define S3C2410_SDICON_CLOCKTYPE      (1<<0)
++
++#define S3C2410_SDICMDCON_ABORT       (1<<12)
++#define S3C2410_SDICMDCON_WITHDATA    (1<<11)
++#define S3C2410_SDICMDCON_LONGRSP     (1<<10)
++#define S3C2410_SDICMDCON_WAITRSP     (1<<9)
++#define S3C2410_SDICMDCON_CMDSTART    (1<<8)
++#define S3C2410_SDICMDCON_SENDERHOST  (1<<6)
++#define S3C2410_SDICMDCON_INDEX       (0x3f)
++
++#define S3C2410_SDICMDSTAT_CRCFAIL    (1<<12)
++#define S3C2410_SDICMDSTAT_CMDSENT    (1<<11)
++#define S3C2410_SDICMDSTAT_CMDTIMEOUT (1<<10)
++#define S3C2410_SDICMDSTAT_RSPFIN     (1<<9)
++#define S3C2410_SDICMDSTAT_XFERING    (1<<8)
++#define S3C2410_SDICMDSTAT_INDEX      (0xff)
++
++#define S3C2440_SDIDCON_DS_BYTE       (0<<22)
++#define S3C2440_SDIDCON_DS_HALFWORD   (1<<22)
++#define S3C2440_SDIDCON_DS_WORD       (2<<22)
++#define S3C2410_SDIDCON_IRQPERIOD     (1<<21)
++#define S3C2410_SDIDCON_TXAFTERRESP   (1<<20)
++#define S3C2410_SDIDCON_RXAFTERCMD    (1<<19)
++#define S3C2410_SDIDCON_BUSYAFTERCMD  (1<<18)
++#define S3C2410_SDIDCON_BLOCKMODE     (1<<17)
++#define S3C2410_SDIDCON_WIDEBUS       (1<<16)
++#define S3C2410_SDIDCON_DMAEN         (1<<15)
++#define S3C2410_SDIDCON_STOP          (1<<14)
++#define S3C2440_SDIDCON_DATSTART      (1<<14)
++#define S3C2410_SDIDCON_DATMODE             (3<<12)
++#define S3C2410_SDIDCON_BLKNUM        (0x7ff)
++
++/* constants for S3C2410_SDIDCON_DATMODE */
++#define S3C2410_SDIDCON_XFER_READY    (0<<12)
++#define S3C2410_SDIDCON_XFER_CHKSTART (1<<12)
++#define S3C2410_SDIDCON_XFER_RXSTART  (2<<12)
++#define S3C2410_SDIDCON_XFER_TXSTART  (3<<12)
++
++#define S3C2410_SDIDCNT_BLKNUM_MASK   (0xFFF)
++#define S3C2410_SDIDCNT_BLKNUM_SHIFT  (12)
++
++#define S3C2410_SDIDSTA_RDYWAITREQ    (1<<10)
++#define S3C2410_SDIDSTA_SDIOIRQDETECT (1<<9)
++#define S3C2410_SDIDSTA_FIFOFAIL      (1<<8)  /* reserved on 2440 */
++#define S3C2410_SDIDSTA_CRCFAIL       (1<<7)
++#define S3C2410_SDIDSTA_RXCRCFAIL     (1<<6)
++#define S3C2410_SDIDSTA_DATATIMEOUT   (1<<5)
++#define S3C2410_SDIDSTA_XFERFINISH    (1<<4)
++#define S3C2410_SDIDSTA_BUSYFINISH    (1<<3)
++#define S3C2410_SDIDSTA_SBITERR       (1<<2)  /* reserved on 2410a/2440 */
++#define S3C2410_SDIDSTA_TXDATAON      (1<<1)
++#define S3C2410_SDIDSTA_RXDATAON      (1<<0)
++
++#define S3C2440_SDIFSTA_FIFORESET      (1<<16)
++#define S3C2440_SDIFSTA_FIFOFAIL       (3<<14)  /* 3 is correct (2 bits) */
++#define S3C2410_SDIFSTA_TFDET          (1<<13)
++#define S3C2410_SDIFSTA_RFDET          (1<<12)
++#define S3C2410_SDIFSTA_TFHALF         (1<<11)
++#define S3C2410_SDIFSTA_TFEMPTY        (1<<10)
++#define S3C2410_SDIFSTA_RFLAST         (1<<9)
++#define S3C2410_SDIFSTA_RFFULL         (1<<8)
++#define S3C2410_SDIFSTA_RFHALF         (1<<7)
++#define S3C2410_SDIFSTA_COUNTMASK      (0x7f)
++
++#define S3C2410_SDIIMSK_RESPONSECRC    (1<<17)
++#define S3C2410_SDIIMSK_CMDSENT        (1<<16)
++#define S3C2410_SDIIMSK_CMDTIMEOUT     (1<<15)
++#define S3C2410_SDIIMSK_RESPONSEND     (1<<14)
++#define S3C2410_SDIIMSK_READWAIT       (1<<13)
++#define S3C2410_SDIIMSK_SDIOIRQ        (1<<12)
++#define S3C2410_SDIIMSK_FIFOFAIL       (1<<11)
++#define S3C2410_SDIIMSK_CRCSTATUS      (1<<10)
++#define S3C2410_SDIIMSK_DATACRC        (1<<9)
++#define S3C2410_SDIIMSK_DATATIMEOUT    (1<<8)
++#define S3C2410_SDIIMSK_DATAFINISH     (1<<7)
++#define S3C2410_SDIIMSK_BUSYFINISH     (1<<6)
++#define S3C2410_SDIIMSK_SBITERR        (1<<5) /* reserved 2440/2410a */
++#define S3C2410_SDIIMSK_TXFIFOHALF     (1<<4)
++#define S3C2410_SDIIMSK_TXFIFOEMPTY    (1<<3)
++#define S3C2410_SDIIMSK_RXFIFOLAST     (1<<2)
++#define S3C2410_SDIIMSK_RXFIFOFULL     (1<<1)
++#define S3C2410_SDIIMSK_RXFIFOHALF     (1<<0)
++
++#endif /* __ASM_ARM_REGS_SDI */
+Index: u-boot/include/s3c24x0.h
+===================================================================
+--- u-boot.orig/include/s3c24x0.h
++++ u-boot/include/s3c24x0.h
+@@ -637,13 +637,7 @@
+       S3C24X0_REG32   SDIDCNT;
+       S3C24X0_REG32   SDIDSTA;
+       S3C24X0_REG32   SDIFSTA;
+-#ifdef __BIG_ENDIAN
+-      S3C24X0_REG8    res[3];
+-      S3C24X0_REG8    SDIDAT;
+-#else
+-      S3C24X0_REG8    SDIDAT;
+-      S3C24X0_REG8    res[3];
+-#endif
++      S3C24X0_REG32   SDIDAT;
+       S3C24X0_REG32   SDIIMSK;
+ } /*__attribute__((__packed__))*/ S3C2410_SDI;
+@@ -1123,11 +1117,7 @@
+ #define rSDIDatCnt            (*(volatile unsigned *)0x5A000030)
+ #define rSDIDatSta            (*(volatile unsigned *)0x5A000034)
+ #define rSDIFSTA              (*(volatile unsigned *)0x5A000038)
+-#ifdef __BIG_ENDIAN
+-#define rSDIDAT                       (*(volatile unsigned char *)0x5A00003F)
+-#else
+-#define rSDIDAT                       (*(volatile unsigned char *)0x5A00003C)
+-#endif
++#define rSDIDAT                       (*(volatile unsigned *)0x5A00003C)
+ #define rSDIIntMsk            (*(volatile unsigned *)0x5A000040)
+ #endif
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-nand.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-nand.patch
new file mode 100644 (file)
index 0000000..dc363bb
--- /dev/null
@@ -0,0 +1,525 @@
+This patch adds NAND (including boot-from-NAND via steppingstone) support to
+the S3C2410 SoC code in u-boot
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+
+Index: u-boot/cpu/arm920t/s3c24x0/Makefile
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/Makefile   2007-02-28 03:47:44.000000000 +0100
++++ u-boot/cpu/arm920t/s3c24x0/Makefile        2007-03-01 14:29:32.000000000 +0100
+@@ -26,7 +26,7 @@
+ LIB   = $(obj)lib$(SOC).a
+ COBJS = i2c.o interrupts.o serial.o speed.o \
+-        usb_ohci.o
++        usb_ohci.o nand_read.o nand.o
+ SRCS  := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+ OBJS  := $(addprefix $(obj),$(SOBJS) $(COBJS))
+Index: u-boot/cpu/arm920t/s3c24x0/nand.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ u-boot/cpu/arm920t/s3c24x0/nand.c  2007-03-01 14:30:27.000000000 +0100
+@@ -0,0 +1,225 @@
++/*
++ * (C) Copyright 2006 OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * 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>
++
++#if 0
++#define DEBUGN        printf
++#else
++#define DEBUGN(x, args ...) {}
++#endif
++
++#if (CONFIG_COMMANDS & CFG_CMD_NAND)
++#if !defined(CFG_NAND_LEGACY)
++
++#include <nand.h>
++#include <s3c2410.h>
++
++#define __REGb(x)     (*(volatile unsigned char *)(x))
++#define __REGi(x)     (*(volatile unsigned int *)(x))
++
++#define       NF_BASE         0x4e000000
++#define       NFCONF          __REGi(NF_BASE + 0x0)
++#define       NFCMD           __REGb(NF_BASE + 0x4)
++#define       NFADDR          __REGb(NF_BASE + 0x8)
++#define       NFDATA          __REGb(NF_BASE + 0xc)
++#define       NFSTAT          __REGb(NF_BASE + 0x10)
++#define NFECC0                __REGb(NF_BASE + 0x14)
++#define NFECC1                __REGb(NF_BASE + 0x15)
++#define NFECC2                __REGb(NF_BASE + 0x16)
++
++#define S3C2410_NFCONF_EN          (1<<15)
++#define S3C2410_NFCONF_512BYTE     (1<<14)
++#define S3C2410_NFCONF_4STEP       (1<<13)
++#define S3C2410_NFCONF_INITECC     (1<<12)
++#define S3C2410_NFCONF_nFCE        (1<<11)
++#define S3C2410_NFCONF_TACLS(x)    ((x)<<8)
++#define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)
++#define S3C2410_NFCONF_TWRPH1(x)   ((x)<<0)
++
++static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd)
++{
++      struct nand_chip *chip = mtd->priv;
++
++      DEBUGN("hwcontrol(): 0x%02x: ", cmd);
++
++      switch (cmd) {
++      case NAND_CTL_SETNCE:
++              NFCONF &= ~S3C2410_NFCONF_nFCE;
++              DEBUGN("NFCONF=0x%08x\n", NFCONF);
++              break;
++      case NAND_CTL_CLRNCE:
++              NFCONF |= S3C2410_NFCONF_nFCE;
++              DEBUGN("NFCONF=0x%08x\n", NFCONF);
++              break;
++      case NAND_CTL_SETALE:
++              chip->IO_ADDR_W = NF_BASE + 0x8;
++              DEBUGN("SETALE\n");
++              break;
++      case NAND_CTL_SETCLE:
++              chip->IO_ADDR_W = NF_BASE + 0x4;
++              DEBUGN("SETCLE\n");
++              break;
++      default:
++              chip->IO_ADDR_W = NF_BASE + 0xc;
++              break;
++      }
++      return;
++}
++
++static int s3c2410_dev_ready(struct mtd_info *mtd)
++{
++      DEBUGN("dev_ready\n");
++      return (NFSTAT & 0x01);
++}
++
++static void s3c2410_cmdfunc(struct mtd_info *mtd, unsigned cmd,
++                          int column, int page_addr)
++{
++      DEBUGN("cmdfunc(): 0x%02x, col=%d, page=%d\n", cmd, column, page_addr);
++
++      switch (cmd) {
++      case NAND_CMD_READ0:
++      case NAND_CMD_READ1:
++      case NAND_CMD_READOOB:
++              NFCMD = cmd;
++              NFADDR = column & 0xff;
++              NFADDR = page_addr & 0xff;
++              NFADDR = (page_addr >> 8) & 0xff;
++              NFADDR = (page_addr >> 16) & 0xff;
++              break;
++      case NAND_CMD_READID:
++              NFCMD = cmd;
++              NFADDR = 0;
++              break;
++      case NAND_CMD_PAGEPROG:
++              NFCMD = cmd;
++              printf("PAGEPROG not implemented\n");
++              break;
++      case NAND_CMD_ERASE1:
++              NFCMD = cmd;
++              NFADDR = page_addr & 0xff;
++              NFADDR = (page_addr >> 8) & 0xff;
++              NFADDR = (page_addr >> 16) & 0xff;
++              break;
++      case NAND_CMD_ERASE2:
++              NFCMD = cmd;
++              break;
++      case NAND_CMD_SEQIN:
++              printf("SEQIN not implemented\n");
++              break;
++      case NAND_CMD_STATUS:
++              NFCMD = cmd;
++              break;
++      case NAND_CMD_RESET:
++              NFCMD = cmd;
++              break;
++      default:
++              break;
++      }
++
++      while (!s3c2410_dev_ready(mtd));
++}
++
++#ifdef CONFIG_S3C2410_NAND_HWECC
++void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
++{
++      DEBUGN("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd ,mode);
++      NFCONF |= S3C2410_NFCONF_INITECC;
++}
++
++static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
++{
++      ecc_code[0] = NFECC0;
++      ecc_code[1] = NFECC1;
++      ecc_code[2] = NFECC2;
++      DEBUGN("s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n", mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
++
++      return 0;
++}
++
++int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
++{
++      if (read_ecc[0] == calc_ecc[0] &&
++          read_ecc[1] == calc_ecc[1] &&
++          read_ecc[2] == calc_ecc[2])
++              return 0;
++
++      printf("s3c2410_nand_correct_data: not implemented\n");
++      return -1;
++}
++#endif
++
++int board_nand_init(struct nand_chip *nand)
++{
++      u_int32_t cfg;
++      u_int8_t tacls, twrph0, twrph1;
++      S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
++
++      DEBUGN("board_nand_init()\n");
++
++      clk_power->CLKCON |= (1 << 4);
++
++      /* initialize hardware */
++      twrph0 = 3; twrph1 = 0; tacls = 0;
++
++      cfg = S3C2410_NFCONF_EN;
++      cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
++      cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
++      cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
++
++      NFCONF = cfg;
++      //NFCONF = 0xf842;
++
++      /* initialize nand_chip data structure */
++      nand->IO_ADDR_R = nand->IO_ADDR_W = 0x4e00000c;
++
++      /* read_buf and write_buf are default */
++      /* read_byte and write_byte are default */
++
++      /* hwcontrol always must be implemented */
++      nand->hwcontrol = s3c2410_hwcontrol;
++
++      nand->dev_ready = s3c2410_dev_ready;
++
++#ifdef CONFIG_S3C2410_NAND_HWECC
++      nand->enable_hwecc = s3c2410_nand_enable_hwecc;
++      nand->calculate_ecc = s3c2410_nand_calculate_ecc;
++      nand->correct_data = s3c2410_nand_correct_data;
++      nand->eccmode = NAND_ECC_HW3_512;
++#else
++      nand->eccmode = NAND_ECC_SOFT;
++#endif
++
++#ifdef CONFIG_S3C2410_NAND_BBT
++      nand->options = NAND_USE_FLASH_BBT;
++#else
++      nand->options = 0;
++#endif
++
++      DEBUGN("end of nand_init\n");
++
++      return 0;
++}
++
++#else
++ #error "U-Boot legacy NAND support not available for S3C2410"
++#endif
++#endif
+Index: u-boot/cpu/arm920t/s3c24x0/nand_read.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ u-boot/cpu/arm920t/s3c24x0/nand_read.c     2007-02-28 03:51:24.000000000 +0100
+@@ -0,0 +1,98 @@
++/*
++ * nand_read.c: Simple NAND read functions for booting from NAND
++ *
++ * This is used by cpu/arm920/start.S assembler code,
++ * and the board-specific linker script must make sure this
++ * file is linked within the first 4kB of NAND flash.
++ *
++ * Taken from GPLv2 licensed vivi bootloader,
++ * Copyright (C) 2002 MIZI Research, Inc.
++ *
++ * Author: Hwang, Chideok <hwang@mizi.com>
++ * Date  : $Date: 2004/02/04 10:37:37 $
++ *
++ * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ */
++
++#include <common.h>
++
++#ifdef CONFIG_S3C2410_NAND_BOOT
++
++#define __REGb(x)     (*(volatile unsigned char *)(x))
++#define __REGi(x)     (*(volatile unsigned int *)(x))
++#define NF_BASE               0x4e000000
++#define NFCONF                __REGi(NF_BASE + 0x0)
++#define NFCMD         __REGb(NF_BASE + 0x4)
++#define NFADDR                __REGb(NF_BASE + 0x8)
++#define NFDATA                __REGb(NF_BASE + 0xc)
++#define NFSTAT                __REGb(NF_BASE + 0x10)
++
++#define BUSY 1
++inline void wait_idle(void)
++{
++      int i;
++
++      while (!(NFSTAT & BUSY))
++              for (i=0; i<10; i++);
++}
++
++#define NAND_SECTOR_SIZE      512
++#define NAND_BLOCK_MASK               (NAND_SECTOR_SIZE - 1)
++#define NAND_PAGE_SIZE                0x4000
++
++/* low level nand read function */
++int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
++{
++      int i, j;
++
++      if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK))
++              return -1;      /* invalid alignment */
++
++      /* chip Enable */
++      NFCONF &= ~0x800;
++      for (i=0; i<10; i++);
++
++      for (i=start_addr; i < (start_addr + size);) {
++#ifdef CONFIG_S3C2410_NAND_SKIP_BAD
++              if (start_addr % NAND_PAGE_SIZE == 0) {
++                      unsigned char data;
++                      NFCMD = 0x50;
++                      NFADDR = 517&0xf;
++                      NFADDR = (i >> 9) & 0xff;
++                      NFADDR = (i >> 17) & 0xff;
++                      NFADDR = (i >> 25) & 0xff;
++                      wait_idle();
++                      data = (NFDATA & 0xff);
++                      if (data != 0xff) {
++                              /* Bad block */
++                              i += NAND_PAGE_SIZE;
++                              size += NAND_PAGE_SIZE;
++                              continue;
++                      }
++              }
++#endif
++              /* READ0 */
++              NFCMD = 0;
++
++              /* Write Address */
++              NFADDR = i & 0xff;
++              NFADDR = (i >> 9) & 0xff;
++              NFADDR = (i >> 17) & 0xff;
++              NFADDR = (i >> 25) & 0xff;
++
++              wait_idle();
++
++              for (j=0; j < NAND_SECTOR_SIZE; j++, i++) {
++                      *buf = (NFDATA & 0xff);
++                      buf++;
++              }
++      }
++
++      /* chip Disable */
++      NFCONF |= 0x800;        /* chip disable */
++
++      return 0;
++}
++
++#endif /* CONFIG_S3C2410_NAND_BOOT */
+Index: u-boot/cpu/arm920t/start.S
+===================================================================
+--- u-boot.orig/cpu/arm920t/start.S    2007-02-28 03:47:44.000000000 +0100
++++ u-boot/cpu/arm920t/start.S 2007-03-01 14:29:22.000000000 +0100
+@@ -5,6 +5,10 @@
+  *  Copyright (c) 2002        Alex Züpke <azu@sysgo.de>
+  *  Copyright (c) 2002        Gary Jennejohn <gj@denx.de>
+  *
++ * S3C2410 NAND portions
++ *  Copyright (c) 2001  MIZI Research, Inc.
++ *  Copyright (c) 2006  OpenMoko, Inc. (Harald Welte <laforge@openmmoko.org>
++ *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+@@ -27,6 +31,7 @@
+ #include <config.h>
+ #include <version.h>
++#include <s3c2410.h>
+ /*
+@@ -161,6 +166,7 @@
+ #endif
+ #ifndef CONFIG_SKIP_RELOCATE_UBOOT
++#ifndef CONFIG_S3C2410_NAND_BOOT
+ 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 */
+@@ -177,6 +183,93 @@
+       stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */
+       cmp     r0, r2                  /* until source end addreee [r2]    */
+       ble     copy_loop
++#else /* NAND_BOOT */
++relocate:
++copy_myself:
++      /* mov  r10, lr */
++
++      @ reset NAND
++      mov     r1, #S3C2410_NAND_BASE
++      ldr     r2, =0xf842             @ initial value enable tacls=3,rph0=6,rph1=0
++      str     r2, [r1, #oNFCONF]
++      ldr     r2, [r1, #oNFCONF]
++      bic     r2, r2, #0x800          @ enable chip
++      str     r2, [r1, #oNFCONF]
++      mov     r2, #0xff               @ RESET command
++      strb    r2, [r1, #oNFCMD]
++      mov     r3, #0                  @ wait
++1:    add     r3, r3, #0x1
++      cmp     r3, #0xa
++      blt     1b
++2:    ldr     r2, [r1, #oNFSTAT]      @ wait ready
++      tst     r2, #0x1
++      beq     2b
++      ldr     r2, [r1, #oNFCONF]
++      orr     r2, r2, #0x800          @ disable chip
++      str     r2, [r1, #oNFCONF]
++
++#if 0
++      @ get ready to call C functions (for nand_read())
++      ldr     sp, DW_STACK_START      @ setup stack pointer
++      mov     fp, #0                  @ no previous frame, so fp=0
++#else
++      ldr     r0, _TEXT_BASE          /* upper 128 KiB: relocated uboot   */
++      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
++
++      @ copy u-boot to RAM
++      ldr     r0, _TEXT_BASE
++      mov     r1, #0x0
++      mov     r2, #CFG_UBOOT_SIZE
++      bl      nand_read_ll
++
++      tst     r0, #0x0
++      beq     ok_nand_read
++#ifdef CONFIG_DEBUG_LL
++bad_nand_read:
++      ldr     r0, STR_FAIL
++      ldr     r1, SerBase
++      bl      PrintWord
++1:    b       1b              @ infinite loop
++#endif
++
++ok_nand_read:
++#ifdef CONFIG_DEBUG_LL
++      ldr     r0, STR_OK
++      ldr     r1, SerBase
++      bl      PrintWord
++#endif
++
++      @ verify
++      mov     r0, #0
++      @ldr    r1, =0x33f00000
++      ldr     r1, _TEXT_BASE
++      mov     r2, #0x400      @ 4 bytes * 1024 = 4K-bytes
++go_next:
++      ldr     r3, [r0], #4
++      ldr     r4, [r1], #4
++      teq     r3, r4
++      bne     notmatch
++      subs    r2, r2, #4
++      beq     done_nand_read
++      bne     go_next
++notmatch:
++#ifdef CONFIG_DEBUG_LL
++      sub     r0, r0, #4
++      ldr     r1, SerBase
++      bl      PrintHexWord
++      ldr     r0, STR_FAIL
++      ldr     r1, SerBase
++      bl      PrintWord
++#endif
++1:    b       1b
++done_nand_read:
++#endif /* NAND_BOOT */
+ #endif        /* CONFIG_SKIP_RELOCATE_UBOOT */
+       /* Set up the stack                                                 */
+Index: u-boot/include/s3c2410.h
+===================================================================
+--- u-boot.orig/include/s3c2410.h      2007-02-28 03:51:24.000000000 +0100
++++ u-boot/include/s3c2410.h   2007-03-01 14:29:22.000000000 +0100
+@@ -38,12 +38,6 @@
+ #define S3C2410_ECCSIZE               512
+ #define S3C2410_ECCBYTES      3
+-typedef enum {
+-      S3C24X0_UART0,
+-      S3C24X0_UART1,
+-      S3C24X0_UART2
+-} S3C24X0_UARTS_NR;
+-
+ /* S3C2410 device base addresses */
+ #define S3C24X0_MEMCTL_BASE           0x48000000
+ #define S3C24X0_USB_HOST_BASE         0x49000000
+@@ -65,9 +59,23 @@
+ #define S3C2410_SDI_BASE              0x5A000000
++#define oNFCONF                       0x00
++#define oNFCMD                        0x04
++#define oNFADDR                       0x08
++#define oNFDATA                       0x0C
++#define oNFSTAT                       0x10
++#define oNFECC                        0x14
++
++#ifndef __ASSEMBLER__
++
+ /* include common stuff */
+ #include <s3c24x0.h>
++typedef enum {
++      S3C24X0_UART0,
++      S3C24X0_UART1,
++      S3C24X0_UART2
++} S3C24X0_UARTS_NR;
+ static inline S3C24X0_MEMCTL * S3C24X0_GetBase_MEMCTL(void)
+ {
+@@ -142,6 +150,7 @@
+       return (S3C2410_SDI * const)S3C2410_SDI_BASE;
+ }
++#endif
+ /* ISR */
+ #define pISR_RESET            (*(unsigned *)(_ISR_STARTADDRESS+0x0))
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-norelocate_irqvec_cpy.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-norelocate_irqvec_cpy.patch
new file mode 100644 (file)
index 0000000..0d5a497
--- /dev/null
@@ -0,0 +1,32 @@
+If we've somehow magically make u-boot end up in RAM (JTAG, ...), then that RAM
+is mapped to 0x30000000 and not 0, so we need to copy the interrupt vectors, etc. 
+
+Index: u-boot/cpu/arm920t/start.S
+===================================================================
+--- u-boot.orig/cpu/arm920t/start.S
++++ u-boot/cpu/arm920t/start.S
+@@ -332,7 +332,23 @@ done_nand_read:
+       strb    r1, [r0]
+ #endif /* CONFIG_S3C2410_NAND_BOOT */
+ done_relocate:
+-#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
++
++#if defined(CONFIG_USE_IRQ) && defined(CONFIG_S3C2410)
++      /* In the case of the S3C2410, if we've somehow magically (JTAG, ...)
++         ended up in RAM, then that ram is mapped to 0x30000000 and not 0.
++         So we need to copy the interrupt vectors, etc.  */
++
++      mov     r0, #0
++      ldr     r1, _TEXT_BASE
++      mov     r2, #0x40
++irqvec_cpy_next:
++      ldr     r3, [r1], #4
++      str     r3, [r0], #4
++      subs    r2, r2, #4
++      bne     irqvec_cpy_next
++#endif /* CONFIG_USE_IRQ */
++
++#endif /* !CONFIG_SKIP_RELOCATE_UBOOT */
+       /* Set up the stack                                                 */
+ stack_setup:
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-warnings-fix.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410-warnings-fix.patch
new file mode 100644 (file)
index 0000000..8cc442a
--- /dev/null
@@ -0,0 +1,98 @@
+Index: u-boot/include/s3c2410.h
+===================================================================
+--- u-boot.orig/include/s3c2410.h      2007-02-16 23:53:20.000000000 +0100
++++ u-boot/include/s3c2410.h   2007-02-16 23:53:21.000000000 +0100
+@@ -69,75 +69,75 @@
+ #include <s3c24x0.h>
+-static inline S3C24X0_MEMCTL * const S3C24X0_GetBase_MEMCTL(void)
++static inline S3C24X0_MEMCTL * S3C24X0_GetBase_MEMCTL(void)
+ {
+       return (S3C24X0_MEMCTL * const)S3C24X0_MEMCTL_BASE;
+ }
+-static inline S3C24X0_USB_HOST * const S3C24X0_GetBase_USB_HOST(void)
++static inline S3C24X0_USB_HOST * S3C24X0_GetBase_USB_HOST(void)
+ {
+       return (S3C24X0_USB_HOST * const)S3C24X0_USB_HOST_BASE;
+ }
+-static inline S3C24X0_INTERRUPT * const S3C24X0_GetBase_INTERRUPT(void)
++static inline S3C24X0_INTERRUPT * S3C24X0_GetBase_INTERRUPT(void)
+ {
+       return (S3C24X0_INTERRUPT * const)S3C24X0_INTERRUPT_BASE;
+ }
+-static inline S3C24X0_DMAS * const S3C24X0_GetBase_DMAS(void)
++static inline S3C24X0_DMAS * S3C24X0_GetBase_DMAS(void)
+ {
+       return (S3C24X0_DMAS * const)S3C24X0_DMA_BASE;
+ }
+-static inline S3C24X0_CLOCK_POWER * const S3C24X0_GetBase_CLOCK_POWER(void)
++static inline S3C24X0_CLOCK_POWER * S3C24X0_GetBase_CLOCK_POWER(void)
+ {
+       return (S3C24X0_CLOCK_POWER * const)S3C24X0_CLOCK_POWER_BASE;
+ }
+-static inline S3C24X0_LCD * const S3C24X0_GetBase_LCD(void)
++static inline S3C24X0_LCD * S3C24X0_GetBase_LCD(void)
+ {
+       return (S3C24X0_LCD * const)S3C24X0_LCD_BASE;
+ }
+-static inline S3C2410_NAND * const S3C2410_GetBase_NAND(void)
++static inline S3C2410_NAND * S3C2410_GetBase_NAND(void)
+ {
+       return (S3C2410_NAND * const)S3C2410_NAND_BASE;
+ }
+-static inline S3C24X0_UART * const S3C24X0_GetBase_UART(S3C24X0_UARTS_NR nr)
++static inline S3C24X0_UART * S3C24X0_GetBase_UART(S3C24X0_UARTS_NR nr)
+ {
+       return (S3C24X0_UART * const)(S3C24X0_UART_BASE + (nr * 0x4000));
+ }
+-static inline S3C24X0_TIMERS * const S3C24X0_GetBase_TIMERS(void)
++static inline S3C24X0_TIMERS * S3C24X0_GetBase_TIMERS(void)
+ {
+       return (S3C24X0_TIMERS * const)S3C24X0_TIMER_BASE;
+ }
+-static inline S3C24X0_USB_DEVICE * const S3C24X0_GetBase_USB_DEVICE(void)
++static inline S3C24X0_USB_DEVICE * S3C24X0_GetBase_USB_DEVICE(void)
+ {
+       return (S3C24X0_USB_DEVICE * const)S3C24X0_USB_DEVICE_BASE;
+ }
+-static inline S3C24X0_WATCHDOG * const S3C24X0_GetBase_WATCHDOG(void)
++static inline S3C24X0_WATCHDOG * S3C24X0_GetBase_WATCHDOG(void)
+ {
+       return (S3C24X0_WATCHDOG * const)S3C24X0_WATCHDOG_BASE;
+ }
+-static inline S3C24X0_I2C * const S3C24X0_GetBase_I2C(void)
++static inline S3C24X0_I2C * S3C24X0_GetBase_I2C(void)
+ {
+       return (S3C24X0_I2C * const)S3C24X0_I2C_BASE;
+ }
+-static inline S3C24X0_I2S * const S3C24X0_GetBase_I2S(void)
++static inline S3C24X0_I2S * S3C24X0_GetBase_I2S(void)
+ {
+       return (S3C24X0_I2S * const)S3C24X0_I2S_BASE;
+ }
+-static inline S3C24X0_GPIO * const S3C24X0_GetBase_GPIO(void)
++static inline S3C24X0_GPIO * S3C24X0_GetBase_GPIO(void)
+ {
+       return (S3C24X0_GPIO * const)S3C24X0_GPIO_BASE;
+ }
+-static inline S3C24X0_RTC * const S3C24X0_GetBase_RTC(void)
++static inline S3C24X0_RTC * S3C24X0_GetBase_RTC(void)
+ {
+       return (S3C24X0_RTC * const)S3C24X0_RTC_BASE;
+ }
+-static inline S3C2410_ADC * const S3C2410_GetBase_ADC(void)
++static inline S3C2410_ADC * S3C2410_GetBase_ADC(void)
+ {
+       return (S3C2410_ADC * const)S3C2410_ADC_BASE;
+ }
+-static inline S3C24X0_SPI * const S3C24X0_GetBase_SPI(void)
++static inline S3C24X0_SPI * S3C24X0_GetBase_SPI(void)
+ {
+       return (S3C24X0_SPI * const)S3C24X0_SPI_BASE;
+ }
+-static inline S3C2410_SDI * const S3C2410_GetBase_SDI(void)
++static inline S3C2410_SDI * S3C2410_GetBase_SDI(void)
+ {
+       return (S3C2410_SDI * const)S3C2410_SDI_BASE;
+ }
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410_fb.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410_fb.patch
new file mode 100644 (file)
index 0000000..b508535
--- /dev/null
@@ -0,0 +1,215 @@
+Index: u-boot/drivers/Makefile
+===================================================================
+--- u-boot.orig/drivers/Makefile
++++ u-boot/drivers/Makefile
+@@ -52,7 +52,7 @@
+         ks8695eth.o \
+         pxa_pcmcia.o mpc8xx_pcmcia.o tqm8xx_pcmcia.o  \
+         rpx_pcmcia.o \
+-        fsl_i2c.o
++        fsl_i2c.o s3c2410_fb.o
+ SRCS  := $(COBJS:.o=.c)
+ OBJS  := $(addprefix $(obj),$(COBJS))
+Index: u-boot/drivers/s3c2410_fb.c
+===================================================================
+--- /dev/null
++++ u-boot/drivers/s3c2410_fb.c
+@@ -0,0 +1,166 @@
++/*
++ * (C) Copyright 2006 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * 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>
++
++#if defined(CONFIG_VIDEO_S3C2410)
++
++#include <video_fb.h>
++#include "videomodes.h"
++#include <s3c2410.h>
++/*
++ * Export Graphic Device
++ */
++GraphicDevice smi;
++
++#define VIDEO_MEM_SIZE        0x200000        /* 480x640x16bit = 614400 bytes */
++
++extern void board_video_init(GraphicDevice *pGD);
++
++/*******************************************************************************
++ *
++ * Init video chip with common Linux graphic modes (lilo)
++ */
++void *video_hw_init (void)
++{
++      S3C24X0_LCD * const lcd = S3C24X0_GetBase_LCD();
++      GraphicDevice *pGD = (GraphicDevice *)&smi;
++      int videomode;
++      unsigned long t1, hsynch, vsynch;
++      char *penv;
++      int tmp, i, bits_per_pixel;
++      struct ctfb_res_modes *res_mode;
++      struct ctfb_res_modes var_mode;
++      unsigned char videoout;
++
++      /* Search for video chip */
++      printf("Video: ");
++
++      tmp = 0;
++
++      videomode = CFG_DEFAULT_VIDEO_MODE;
++      /* get video mode via environment */
++      if ((penv = getenv ("videomode")) != NULL) {
++              /* deceide if it is a string */
++              if (penv[0] <= '9') {
++                      videomode = (int) simple_strtoul (penv, NULL, 16);
++                      tmp = 1;
++              }
++      } else {
++              tmp = 1;
++      }
++      if (tmp) {
++              /* parameter are vesa modes */
++              /* search params */
++              for (i = 0; i < VESA_MODES_COUNT; i++) {
++                      if (vesa_modes[i].vesanr == videomode)
++                              break;
++              }
++              if (i == VESA_MODES_COUNT) {
++                      printf ("no VESA Mode found, switching to mode 0x%x ", CFG_DEFAULT_VIDEO_MODE);
++                      i = 0;
++              }
++              res_mode =
++                      (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
++                                                               resindex];
++              bits_per_pixel = vesa_modes[i].bits_per_pixel;
++      } else {
++
++              res_mode = (struct ctfb_res_modes *) &var_mode;
++              bits_per_pixel = video_get_params (res_mode, penv);
++      }
++
++      /* calculate hsynch and vsynch freq (info only) */
++      t1 = (res_mode->left_margin + res_mode->xres +
++            res_mode->right_margin + res_mode->hsync_len) / 8;
++      t1 *= 8;
++      t1 *= res_mode->pixclock;
++      t1 /= 1000;
++      hsynch = 1000000000L / t1;
++      t1 *=
++              (res_mode->upper_margin + res_mode->yres +
++               res_mode->lower_margin + res_mode->vsync_len);
++      t1 /= 1000;
++      vsynch = 1000000000L / t1;
++
++      /* fill in Graphic device struct */
++      sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
++               res_mode->yres, bits_per_pixel, (hsynch / 1000),
++               (vsynch / 1000));
++      printf ("%s\n", pGD->modeIdent);
++      pGD->winSizeX = res_mode->xres;
++      pGD->winSizeY = res_mode->yres;
++      pGD->plnSizeX = res_mode->xres;
++      pGD->plnSizeY = res_mode->yres;
++      switch (bits_per_pixel) {
++      case 8:
++              pGD->gdfBytesPP = 1;
++              pGD->gdfIndex = GDF__8BIT_INDEX;
++              break;
++      case 15:
++              pGD->gdfBytesPP = 2;
++              pGD->gdfIndex = GDF_15BIT_555RGB;
++              break;
++      case 16:
++              pGD->gdfBytesPP = 2;
++              pGD->gdfIndex = GDF_16BIT_565RGB;
++              break;
++      case 24:
++              pGD->gdfBytesPP = 3;
++              pGD->gdfIndex = GDF_24BIT_888RGB;
++              break;
++      }
++
++      /* statically configure settings */
++      pGD->winSizeX = pGD->plnSizeX = 480;
++      pGD->winSizeY = pGD->plnSizeY = 640;
++      pGD->gdfBytesPP = 2;
++      pGD->gdfIndex = GDF_16BIT_565RGB;
++
++      pGD->frameAdrs = LCD_VIDEO_ADDR;
++      pGD->memSize = VIDEO_MEM_SIZE;
++
++      board_video_init(pGD);
++
++      lcd->LCDSADDR1 = pGD->frameAdrs >> 1;
++
++      /* This marks the end of the frame buffer. */
++      lcd->LCDSADDR2 = (lcd->LCDSADDR1&0x1fffff) + (pGD->winSizeX+0) * pGD->winSizeY;
++      lcd->LCDSADDR3 = pGD->winSizeX;
++
++      /* Clear video memory */
++      memset(pGD->frameAdrs, 0, pGD->memSize);
++
++      /* Enable  Display  */
++      lcd->LCDCON1 |= 0x01;   /* ENVID = 1 */
++
++      return ((void*)&smi);
++}
++
++void
++video_set_lut (unsigned int index,    /* color number */
++             unsigned char r, /* red */
++             unsigned char g, /* green */
++             unsigned char b  /* blue */
++    )
++{
++}
++
++#endif /* CONFIG_VIDEO_S3C2410 */
+Index: u-boot/drivers/cfb_console.c
+===================================================================
+--- u-boot.orig/drivers/cfb_console.c
++++ u-boot/drivers/cfb_console.c
+@@ -141,6 +141,14 @@
+ #endif
+ /*****************************************************************************/
++/* Defines for the S3C2410 driver                                          */
++/*****************************************************************************/
++#ifdef CONFIG_VIDEO_S3C2410
++/* it actually is little-endian, but the host CPU, too ! */
++//#define VIDEO_FB_LITTLE_ENDIAN
++#endif
++
++/*****************************************************************************/
+ /* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc           */
+ /*****************************************************************************/
+ #include <video_fb.h>
+@@ -307,6 +315,11 @@
+ #define SHORTSWAP32(x)         (x)
+ #endif
++#ifdef CONFIG_VIDEO_S3C2410
++#undef SHORTSWAP32
++#define       SHORTSWAP32(x)  ((((x) & 0xffff) << 16) | (((x) >> 16) & 0xffff))
++#endif
++
+ #if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE)
+ #define PRINTD(x)       printf(x)
+ #else
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410_udc.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2410_udc.patch
new file mode 100644 (file)
index 0000000..16bee3e
--- /dev/null
@@ -0,0 +1,1263 @@
+USB Device Controller Driver for Samsung S3C2410 SoC
+
+Index: u-boot/drivers/Makefile
+===================================================================
+--- u-boot.orig/drivers/Makefile
++++ u-boot/drivers/Makefile
+@@ -47,7 +47,7 @@
+         status_led.o sym53c8xx.o systemace.o ahci.o \
+         ti_pci1410a.o tigon3.o tsec.o \
+         tsi108_eth.o tsi108_i2c.o tsi108_pci.o \
+-        usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \
++        usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbdcore_s3c2410.o usbtty.o \
+         videomodes.o w83c553f.o \
+         ks8695eth.o \
+         pcf50606.o \
+Index: u-boot/drivers/usbdcore_s3c2410.c
+===================================================================
+--- /dev/null
++++ u-boot/drivers/usbdcore_s3c2410.c
+@@ -0,0 +1,730 @@
++/* S3C2410 USB Device Controller Driver for u-boot
++ *
++ * (C) Copyright 2007 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * based on Linux' s3c2410_udc.c, which is
++ * Copyright (C) 2004-2006 Herbert Pötzl - Arnaud Patard
++ *
++ * 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>
++
++#if defined(CONFIG_S3C2410) && defined(CONFIG_USB_DEVICE)
++
++#include <common.h>
++
++/* we can't use the regular debug macros since the console might be
++ * set to usbtty, which would cause deadlocks! */
++#ifdef        DEBUG
++#undef debug
++#undef debugX
++#define debug(fmt,args...)    serial_printf (fmt ,##args)
++#define debugX(level,fmt,args...) if (DEBUG>=level) serial_printf(fmt,##args)
++#endif
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#include <asm/io.h>
++#include <s3c2410.h>
++
++#include "usbdcore.h"
++#include "usbdcore_s3c2410.h"
++#include "usbdcore_ep0.h"
++#include <usb_cdc_acm.h>
++
++enum ep0_state {
++        EP0_IDLE,
++        EP0_IN_DATA_PHASE,
++        EP0_OUT_DATA_PHASE,
++        EP0_END_XFER,
++        EP0_STALL,
++};
++
++static struct urb *ep0_urb = NULL;
++
++static struct usb_device_instance *udc_device;        /* Used in interrupt handler */
++
++static inline int fifo_count_out(void)
++{
++      int tmp;
++
++      tmp = inl(S3C2410_UDC_OUT_FIFO_CNT2_REG) << 8;
++      tmp |= inl(S3C2410_UDC_OUT_FIFO_CNT1_REG);
++
++      return tmp & 0xffff;
++}
++
++static const unsigned long ep_fifo_reg[S3C2410_UDC_NUM_ENDPOINTS] = {
++      S3C2410_UDC_EP0_FIFO_REG,
++      S3C2410_UDC_EP1_FIFO_REG,
++      S3C2410_UDC_EP2_FIFO_REG,
++      S3C2410_UDC_EP3_FIFO_REG,
++      S3C2410_UDC_EP4_FIFO_REG,
++};
++
++static int s3c2410_write_noniso_tx_fifo(struct usb_endpoint_instance *endpoint)
++{
++      struct urb *urb = endpoint->tx_urb;
++      unsigned int last, i;
++      unsigned int ep = endpoint->endpoint_address & 0x7f;
++      unsigned long fifo_reg = ep_fifo_reg[ep];
++
++      /* WARNING: don't ever put serial debug printf's in non-error codepaths
++       * here, it is called from the time critical EP0 codepath ! */
++
++      if (!urb || ep >= S3C2410_UDC_NUM_ENDPOINTS) {
++              serial_printf("no urb or wrong endpoint\n");
++              return -1;
++      }
++
++      S3C2410_UDC_SETIX(ep);
++      if ((last = MIN(urb->actual_length - endpoint->sent,
++                      endpoint->tx_packetSize))) {
++              u8 *cp = urb->buffer + endpoint->sent;
++
++              for (i = 0; i < last; i++)
++                      outb(*(cp+i), fifo_reg);
++      }
++      endpoint->last = last;
++
++      if (endpoint->sent + last < urb->actual_length) {
++              /* not all data has been transmitted so far */
++              return 0;
++      }
++
++      if (last == endpoint->tx_packetSize) {
++              /* we need to send one more packet (ZLP) */
++              return 0;
++      }
++
++      return 1;
++}
++
++
++static void s3c2410_deconfigure_device (void)
++{
++      /* FIXME: Implement this */
++}
++
++static void s3c2410_configure_device (struct usb_device_instance *device)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++      S3C24X0_CLOCK_POWER * const cpower = S3C24X0_GetBase_CLOCK_POWER();
++
++      /* disable EP0-4 SUBD interrupts ? */
++      outl(0x00, S3C2410_UDC_USB_INT_EN_REG);
++
++      /* UPLL already configured by board-level init code */
++
++      /* configure USB pads to device mode */
++      gpio->MISCCR &= ~(S3C2410_MISCCR_USBHOST|S3C2410_MISCCR_USBSUSPND1);
++
++      /* don't disable USB clock */
++      cpower->CLKSLOW &= ~S3C2410_CLKSLOW_UCLK_OFF;
++
++      /* clear interrupt registers */
++      inl(S3C2410_UDC_EP_INT_REG);
++      inl(S3C2410_UDC_USB_INT_REG);
++      outl(0xff, S3C2410_UDC_EP_INT_REG);
++      outl(0xff, S3C2410_UDC_USB_INT_REG);
++
++      /* enable USB interrupts for RESET and SUSPEND/RESUME */
++      outl(S3C2410_UDC_USBINT_RESET|S3C2410_UDC_USBINT_SUSPEND,
++           S3C2410_UDC_USB_INT_EN_REG);
++}
++
++static void udc_set_address(unsigned char address)
++{
++      address |= 0x80; /* ADDR_UPDATE bit */
++      outl(address, S3C2410_UDC_FUNC_ADDR_REG);
++}
++
++extern struct usb_device_descriptor device_descriptor;
++
++static void s3c2410_udc_ep0(void)
++{
++      u_int8_t ep0csr;
++      struct usb_endpoint_instance *ep0 = udc_device->bus->endpoint_array;
++
++      S3C2410_UDC_SETIX(0);
++      ep0csr = inl(S3C2410_UDC_IN_CSR1_REG);
++
++      /* clear stall status */
++      if (ep0csr & S3C2410_UDC_EP0_CSR_SENTSTL) {
++              serial_printf("Clearing SENT_STALL\n");
++              clear_ep0_sst();
++              if (ep0csr & S3C2410_UDC_EP0_CSR_SOPKTRDY)
++                      clear_ep0_opr();
++              ep0->state = EP0_IDLE;
++              return;
++      }
++
++      /* clear setup end */
++      if (ep0csr & S3C2410_UDC_EP0_CSR_SE
++          /* && ep0->state != EP0_IDLE */) {
++              serial_printf("Clearing SETUP_END\n");
++              clear_ep0_se();
++#if 1
++              if (ep0csr & S3C2410_UDC_EP0_CSR_SOPKTRDY) {
++                      /* Flush FIFO */
++                      while (inl(S3C2410_UDC_OUT_FIFO_CNT1_REG))
++                              inl(S3C2410_UDC_EP0_FIFO_REG);
++                      clear_ep0_opr();
++              }
++#endif
++              ep0->state = EP0_IDLE;
++              return;
++      }
++
++      /* Don't ever put [serial] debugging in non-error codepaths here, it
++       * will violate the tight timing constraints of this USB Device
++       * controller (and lead to bus enumeration failures) */
++
++      switch (ep0->state) {
++              int i, fifo_count;
++              unsigned char *datap;
++      case EP0_IDLE:
++              if (!(ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY))
++                      break;
++
++              datap = (unsigned char *) &ep0_urb->device_request;
++              /* host->device packet has been received */
++
++              /* pull it out of the fifo */
++              fifo_count = fifo_count_out();
++              for (i = 0; i < fifo_count; i++) {
++                      *datap = (unsigned char)inl(S3C2410_UDC_EP0_FIFO_REG);
++                      datap++;
++              }
++              if (fifo_count != 8) {
++                      debug("STRANGE FIFO COUNT: %u bytes\n", fifo_count);
++                      set_ep0_ss();
++                      return;
++              }
++
++              if (ep0_urb->device_request.wLength == 0) {
++                      if (ep0_recv_setup(ep0_urb)) {
++                              /* Not a setup packet, stall next EP0 transaction */
++                              debug("can't parse setup packet1\n");
++                              set_ep0_ss();
++                              set_ep0_de_out();
++                              ep0->state = EP0_IDLE;
++                              return;
++                      }
++                      /* There are some requests with which we need to deal
++                       * manually here */
++                      switch (ep0_urb->device_request.bRequest) {
++                      case USB_REQ_SET_CONFIGURATION:
++                              if (!ep0_urb->device_request.wValue)
++                                      usbd_device_event_irq(udc_device,
++                                                      DEVICE_DE_CONFIGURED, 0);
++                              else
++                                      usbd_device_event_irq(udc_device,
++                                                      DEVICE_CONFIGURED, 0);
++                              break;
++                      case USB_REQ_SET_ADDRESS:
++                              udc_set_address(udc_device->address);
++                              usbd_device_event_irq(udc_device,
++                                              DEVICE_ADDRESS_ASSIGNED, 0);
++                              break;
++                      default:
++                              break;
++                      }
++                      set_ep0_de_out();
++                      ep0->state = EP0_IDLE;
++              } else {
++                      if ((ep0_urb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
++                          == USB_REQ_HOST2DEVICE) {
++                              clear_ep0_opr();
++                              ep0->state = EP0_OUT_DATA_PHASE;
++                              ep0_urb->buffer = ep0_urb->buffer_data;
++                              ep0_urb->buffer_length = sizeof(ep0_urb->buffer_data);
++                              ep0_urb->actual_length = 0;
++                      } else {
++                              ep0->state = EP0_IN_DATA_PHASE;
++
++                              if (ep0_recv_setup(ep0_urb)) {
++                                      /* Not a setup packet, stall next EP0 transaction */
++                                      debug("can't parse setup packet2\n");
++                                      set_ep0_ss();
++                                      //set_ep0_de_out();
++                                      ep0->state = EP0_IDLE;
++                                      return;
++                              }
++                              clear_ep0_opr();
++                              ep0->tx_urb = ep0_urb;
++                              ep0->sent = ep0->last = 0;
++
++                              if (s3c2410_write_noniso_tx_fifo(ep0)) {
++                                      ep0->state = EP0_IDLE;
++                                      set_ep0_de_in();
++                              } else
++                                      set_ep0_ipr();
++                      }
++              }
++              break;
++      case EP0_IN_DATA_PHASE:
++              if (!(ep0csr & S3C2410_UDC_EP0_CSR_IPKRDY)) {
++                      ep0->sent += ep0->last;
++
++                      if (s3c2410_write_noniso_tx_fifo(ep0)) {
++                              ep0->state = EP0_IDLE;
++                              set_ep0_de_in();
++                      } else
++                              set_ep0_ipr();
++              }
++              break;
++      case EP0_OUT_DATA_PHASE:
++              if (ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY) {
++                      u32 urb_avail = ep0_urb->buffer_length - ep0_urb->actual_length;
++                      u_int8_t *cp = ep0_urb->buffer + ep0_urb->actual_length;
++                      int i, fifo_count;
++
++                      fifo_count = fifo_count_out();
++                      if (fifo_count < urb_avail)
++                              urb_avail = fifo_count;
++
++                      for (i = 0; i < urb_avail; i++)
++                              *cp++ = inl(S3C2410_UDC_EP0_FIFO_REG);
++
++                      ep0_urb->actual_length += urb_avail;
++
++                      if (fifo_count < ep0->rcv_packetSize ||
++                          ep0_urb->actual_length >= ep0_urb->device_request.wLength) {
++                              ep0->state = EP0_IDLE;
++                              if (ep0_recv_setup(ep0_urb)) {
++                                      /* Not a setup packet, stall next EP0 transaction */
++                                      debug("can't parse setup packet3\n");
++                                      set_ep0_ss();
++                                      //set_ep0_de_out();
++                                      return;
++                              }
++                              set_ep0_de_out();
++                      } else
++                              clear_ep0_opr();
++              }
++              break;
++      case EP0_END_XFER:
++              ep0->state = EP0_IDLE;
++              break;
++      case EP0_STALL:
++              //set_ep0_ss;
++              ep0->state = EP0_IDLE;
++              break;
++      }
++}
++
++
++static void s3c2410_udc_epn(int ep)
++{
++      struct usb_endpoint_instance *endpoint;
++      struct urb *urb;
++      u32 ep_csr1;
++
++      if (ep >= S3C2410_UDC_NUM_ENDPOINTS)
++              return;
++
++      endpoint = &udc_device->bus->endpoint_array[ep];
++
++      S3C2410_UDC_SETIX(ep);
++
++      if (endpoint->endpoint_address & USB_DIR_IN) {
++              /* IN transfer (device to host) */
++              ep_csr1 = inl(S3C2410_UDC_IN_CSR1_REG);
++              debug("for ep=%u, CSR1=0x%x ", ep, ep_csr1);
++
++              urb = endpoint->tx_urb;
++              if (ep_csr1 & S3C2410_UDC_ICSR1_SENTSTL) {
++                      /* Stall handshake */
++                      debug("stall\n");
++                      outl(0x00, S3C2410_UDC_IN_CSR1_REG);
++                      return;
++              }
++              if (!(ep_csr1 & S3C2410_UDC_ICSR1_PKTRDY) && urb &&
++                    urb->actual_length) {
++
++                      debug("completing previously send data ");
++                      usbd_tx_complete(endpoint);
++
++                      /* push pending data into FIFO */
++                      if ((endpoint->last == endpoint->tx_packetSize) &&
++                          (urb->actual_length - endpoint->sent - endpoint->last == 0)) {
++                              endpoint->sent += endpoint->last;
++                              /* Write 0 bytes of data (ZLP) */
++                              debug("ZLP ");
++                              outl(ep_csr1|S3C2410_UDC_ICSR1_PKTRDY, S3C2410_UDC_IN_CSR1_REG);
++                      } else {
++                              /* write actual data to fifo */
++                              debug("TX_DATA ");
++                              s3c2410_write_noniso_tx_fifo(endpoint);
++                              outl(ep_csr1|S3C2410_UDC_ICSR1_PKTRDY, S3C2410_UDC_IN_CSR1_REG);
++                      }
++              }
++              debug("\n");
++      } else {
++              /* OUT transfer (host to device) */
++              ep_csr1 = inl(S3C2410_UDC_OUT_CSR1_REG);
++              debug("for ep=%u, CSR1=0x%x ", ep, ep_csr1);
++
++              urb = endpoint->rcv_urb;
++              if (ep_csr1 & S3C2410_UDC_OCSR1_SENTSTL) {
++                      /* Stall handshake */
++                      outl(0x00, S3C2410_UDC_IN_CSR1_REG);
++                      return;
++              }
++              if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && urb) {
++                      /* Read pending data from fifo */
++                      u32 fifo_count = fifo_count_out();
++                      int is_last = 0;
++                      u32 i, urb_avail = urb->buffer_length - urb->actual_length;
++                      u8 *cp = urb->buffer + urb->actual_length;
++
++                      if (fifo_count < endpoint->rcv_packetSize)
++                              is_last = 1;
++
++                      debug("fifo_count=%u is_last=%, urb_avail=%u)\n",
++                              fifo_count, is_last, urb_avail);
++
++                      if (fifo_count < urb_avail)
++                              urb_avail = fifo_count;
++
++                      for (i = 0; i < urb_avail; i++)
++                              *cp++ = inb(ep_fifo_reg[ep]);
++
++                      if (is_last)
++                              outl(ep_csr1 & ~S3C2410_UDC_OCSR1_PKTRDY,
++                                   S3C2410_UDC_OUT_CSR1_REG);
++
++                      usbd_rcv_complete(endpoint, urb_avail, 0);
++              }
++      }
++
++      urb = endpoint->rcv_urb;
++}
++
++/*
++-------------------------------------------------------------------------------
++*/
++
++/* this is just an empty wrapper for usbtty who assumes polling operation */
++void udc_irq(void)
++{
++}
++
++/* Handle general USB interrupts and dispatch according to type.
++ * This function implements TRM Figure 14-13.
++ */
++void s3c2410_udc_irq(void)
++{
++      struct usb_endpoint_instance *ep0 = udc_device->bus->endpoint_array;
++      u_int32_t save_idx = inl(S3C2410_UDC_INDEX_REG);
++
++      /* read interrupt sources */
++      u_int32_t usb_status = inl(S3C2410_UDC_USB_INT_REG);
++      u_int32_t usbd_status = inl(S3C2410_UDC_EP_INT_REG);
++
++      //debug("< IRQ usbs=0x%02x, usbds=0x%02x start >", usb_status, usbd_status);
++
++      /* clear interrupts */
++      outl(usb_status, S3C2410_UDC_USB_INT_REG);
++
++      if (usb_status & S3C2410_UDC_USBINT_RESET) {
++              //serial_putc('R');
++              debug("RESET pwr=0x%x\n", inl(S3C2410_UDC_PWR_REG));
++              udc_setup_ep(udc_device, 0, ep0);
++              outl(S3C2410_UDC_EP0_CSR_SSE|S3C2410_UDC_EP0_CSR_SOPKTRDY, S3C2410_UDC_EP0_CSR_REG);
++              ep0->state = EP0_IDLE;
++              usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
++      }
++
++      if (usb_status & S3C2410_UDC_USBINT_RESUME) {
++              debug("RESUME\n");
++              usbd_device_event_irq(udc_device, DEVICE_BUS_ACTIVITY, 0);
++      }
++
++      if (usb_status & S3C2410_UDC_USBINT_SUSPEND) {
++              debug("SUSPEND\n");
++              usbd_device_event_irq(udc_device, DEVICE_BUS_INACTIVE, 0);
++      }
++
++      /* Endpoint Interrupts */
++      if (usbd_status) {
++              int i;
++
++              if (usbd_status & S3C2410_UDC_INT_EP0) {
++                      outl(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_REG);
++                      s3c2410_udc_ep0();
++              }
++
++              for (i = 1; i < 5; i++) {
++                      u_int32_t tmp = 1 << i;
++
++                      if (usbd_status & tmp) {
++                              /* FIXME: Handle EP X */
++                              outl(tmp, S3C2410_UDC_EP_INT_REG);
++                              s3c2410_udc_epn(i);
++                      }
++              }
++      }
++      S3C2410_UDC_SETIX(save_idx);
++}
++
++/*
++-------------------------------------------------------------------------------
++*/
++
++
++/*
++ * Start of public functions.
++ */
++
++/* Called to start packet transmission. */
++void udc_endpoint_write (struct usb_endpoint_instance *endpoint)
++{
++      unsigned short epnum =
++              endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
++
++      debug("Entering for ep %x ", epnum);
++
++      if (endpoint->tx_urb) {
++              u32 ep_csr1;
++              debug("We have an URB, transmitting\n");
++
++              s3c2410_write_noniso_tx_fifo(endpoint);
++
++              S3C2410_UDC_SETIX(epnum);
++
++              ep_csr1 = inl(S3C2410_UDC_IN_CSR1_REG);
++              outl(ep_csr1|S3C2410_UDC_ICSR1_PKTRDY, S3C2410_UDC_IN_CSR1_REG);
++      } else
++              debug("\n");
++}
++
++/* Start to initialize h/w stuff */
++int udc_init (void)
++{
++      S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
++      S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
++
++      udc_device = NULL;
++
++      /* Set and check clock control.
++       * We might ought to be using the clock control API to do
++       * this instead of fiddling with the clock registers directly
++       * here.
++       */
++      clk_power->CLKCON |= (1 << 7);
++
++      /* Print banner with device revision */
++      printf("USB:   S3C2410 USB Deviced\n");
++
++      /*
++       * At this point, device is ready for configuration...
++       */
++      outl(0x00, S3C2410_UDC_EP_INT_EN_REG);
++      outl(0x00, S3C2410_UDC_USB_INT_EN_REG);
++
++      irq->INTMSK &= ~BIT_USBD;
++
++      return 0;
++}
++
++/*
++ * udc_setup_ep - setup endpoint
++ *
++ * Associate a physical endpoint with endpoint_instance
++ */
++int udc_setup_ep (struct usb_device_instance *device,
++                 unsigned int ep, struct usb_endpoint_instance *endpoint)
++{
++      int ep_addr = endpoint->endpoint_address;
++      int packet_size;
++      int attributes;
++      u_int32_t maxp;
++
++      S3C2410_UDC_SETIX(ep);
++
++      if (ep) {
++              if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
++                      /* IN endpoint */
++                      outl(S3C2410_UDC_ICSR1_FFLUSH|S3C2410_UDC_ICSR1_CLRDT,
++                           S3C2410_UDC_IN_CSR1_REG);
++                      outl(S3C2410_UDC_ICSR2_MODEIN, S3C2410_UDC_IN_CSR2_REG);
++                      packet_size = endpoint->tx_packetSize;
++                      attributes = endpoint->tx_attributes;
++              } else {
++                      /* OUT endpoint */
++                      outl(S3C2410_UDC_ICSR1_CLRDT, S3C2410_UDC_IN_CSR1_REG);
++                      outl(0, S3C2410_UDC_IN_CSR2_REG);
++                      outl(S3C2410_UDC_OCSR1_FFLUSH|S3C2410_UDC_OCSR1_CLRDT,
++                           S3C2410_UDC_OUT_CSR1_REG);
++                      outl(0, S3C2410_UDC_OUT_CSR2_REG);
++                      packet_size = endpoint->rcv_packetSize;
++                      attributes = endpoint->rcv_attributes;
++              }
++      } else
++              packet_size = endpoint->tx_packetSize;
++
++      switch (packet_size) {
++      case 8:
++              maxp = S3C2410_UDC_MAXP_8;
++              break;
++      case 16:
++              maxp = S3C2410_UDC_MAXP_16;
++              break;
++      case 32:
++              maxp = S3C2410_UDC_MAXP_32;
++              break;
++      case 64:
++              maxp = S3C2410_UDC_MAXP_64;
++              break;
++      default:
++              debug("invalid packet size %u\n", packet_size);
++              return -1;
++      }
++
++      debug("setting up endpoint %u addr %x packet_size %u maxp %u\n", ep,
++              endpoint->endpoint_address, packet_size, maxp);
++
++      /* Set maximum packet size */
++      writel(maxp, S3C2410_UDC_MAXP_REG);
++
++      return 0;
++}
++
++/* ************************************************************************** */
++
++/**
++ * udc_connected - is the USB cable connected
++ *
++ * Return non-zero if cable is connected.
++ */
++#if 0
++int udc_connected (void)
++{
++      return ((inw (UDC_DEVSTAT) & UDC_ATT) == UDC_ATT);
++}
++#endif
++
++/* Turn on the USB connection by enabling the pullup resistor */
++void udc_connect (void)
++{
++      debug("connect, enable Pullup\n");
++      S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
++
++      udc_ctrl(UDC_CTRL_PULLUP_ENABLE, 0);
++      udelay(10000);
++      udc_ctrl(UDC_CTRL_PULLUP_ENABLE, 1);
++
++      irq->INTMSK &= ~BIT_USBD;
++}
++
++/* Turn off the USB connection by disabling the pullup resistor */
++void udc_disconnect (void)
++{
++      debug("disconnect, disable Pullup\n");
++      S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
++
++      udc_ctrl(UDC_CTRL_PULLUP_ENABLE, 0);
++
++      /* Disable interrupt (we don't want to get interrupts while the kernel
++       * is relocating itself */
++      irq->INTMSK |= BIT_USBD;
++}
++
++/* Switch on the UDC */
++void udc_enable (struct usb_device_instance *device)
++{
++      debug("enable device %p, status %d\n", device, device->status);
++
++      /* Save the device structure pointer */
++      udc_device = device;
++
++      /* Setup ep0 urb */
++      if (!ep0_urb)
++              ep0_urb = usbd_alloc_urb(udc_device,
++                                       udc_device->bus->endpoint_array);
++      else
++              serial_printf("udc_enable: ep0_urb already allocated %p\n",
++                             ep0_urb);
++
++      s3c2410_configure_device(device);
++}
++
++/* Switch off the UDC */
++void udc_disable (void)
++{
++      debug("disable UDC\n");
++
++      s3c2410_deconfigure_device();
++
++      /* Free ep0 URB */
++      if (ep0_urb) {
++              /*usbd_dealloc_urb(ep0_urb); */
++              ep0_urb = NULL;
++      }
++
++      /* Reset device pointer.
++       * We ought to do this here to balance the initialization of udc_device
++       * in udc_enable, but some of our other exported functions get called
++       * by the bus interface driver after udc_disable, so we have to hang on
++       * to the device pointer to avoid a null pointer dereference. */
++      /* udc_device = NULL; */
++}
++
++/**
++ * udc_startup - allow udc code to do any additional startup
++ */
++void udc_startup_events (struct usb_device_instance *device)
++{
++      /* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */
++      usbd_device_event_irq (device, DEVICE_INIT, 0);
++
++      /* The DEVICE_CREATE event puts the USB device in the state
++       * STATE_ATTACHED.
++       */
++      usbd_device_event_irq (device, DEVICE_CREATE, 0);
++
++      /* Some USB controller driver implementations signal
++       * DEVICE_HUB_CONFIGURED and DEVICE_RESET events here.
++       * DEVICE_HUB_CONFIGURED causes a transition to the state STATE_POWERED,
++       * and DEVICE_RESET causes a transition to the state STATE_DEFAULT.
++       * The OMAP USB client controller has the capability to detect when the
++       * USB cable is connected to a powered USB bus via the ATT bit in the
++       * DEVSTAT register, so we will defer the DEVICE_HUB_CONFIGURED and
++       * DEVICE_RESET events until later.
++       */
++
++      /* The GTA01 can detect usb device attachment, but we just assume being
++       * attached for now (go to STATE_POWERED) */
++      usbd_device_event_irq (device, DEVICE_HUB_CONFIGURED, 0);
++
++      udc_enable (device);
++}
++
++void udc_set_nak(int epid)
++{
++      /* FIXME: implement this */
++}
++
++void udc_unset_nak(int epid)
++{
++      /* FIXME: implement this */
++}
++
++#endif /* CONFIG_S3C2410 && CONFIG_USB_DEVICE */
+Index: u-boot/drivers/usbdcore_s3c2410.h
+===================================================================
+--- /dev/null
++++ u-boot/drivers/usbdcore_s3c2410.h
+@@ -0,0 +1,273 @@
++/* linux/include/asm/arch-s3c2410/regs-udc.h
++ *
++ * Copyright (C) 2004 Herbert Poetzl <herbert@13thfloor.at>
++ *
++ * This include file 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.
++ *
++ *  Changelog:
++ *    01-08-2004      Initial creation
++ *    12-09-2004      Cleanup for submission
++ *    24-10-2004      Fixed S3C2410_UDC_MAXP_REG definition
++ *    10-03-2005      Changed S3C2410_VA to S3C24XX_VA
++ *    10-01-2007      Modify for u-boot
++ */
++
++#ifndef __ASM_ARCH_REGS_UDC_H
++#define __ASM_ARCH_REGS_UDC_H
++
++#define S3C2410_UDC_REG_BASE_PHYS     0x52000000
++#define S3C2410_UDC_NUM_ENDPOINTS     5
++
++#define S3C2410_USBDREG(x) (x + S3C2410_UDC_REG_BASE_PHYS)
++
++#define S3C2410_UDC_FUNC_ADDR_REG     S3C2410_USBDREG(0x0140)
++#define S3C2410_UDC_PWR_REG           S3C2410_USBDREG(0x0144)
++#define S3C2410_UDC_EP_INT_REG                S3C2410_USBDREG(0x0148)
++
++#define S3C2410_UDC_USB_INT_REG               S3C2410_USBDREG(0x0158)
++#define S3C2410_UDC_EP_INT_EN_REG     S3C2410_USBDREG(0x015c)
++
++#define S3C2410_UDC_USB_INT_EN_REG    S3C2410_USBDREG(0x016c)
++
++#define S3C2410_UDC_FRAME_NUM1_REG    S3C2410_USBDREG(0x0170)
++#define S3C2410_UDC_FRAME_NUM2_REG    S3C2410_USBDREG(0x0174)
++
++#define S3C2410_UDC_EP0_FIFO_REG      S3C2410_USBDREG(0x01c0)
++#define S3C2410_UDC_EP1_FIFO_REG      S3C2410_USBDREG(0x01c4)
++#define S3C2410_UDC_EP2_FIFO_REG      S3C2410_USBDREG(0x01c8)
++#define S3C2410_UDC_EP3_FIFO_REG      S3C2410_USBDREG(0x01cc)
++#define S3C2410_UDC_EP4_FIFO_REG      S3C2410_USBDREG(0x01d0)
++
++#define S3C2410_UDC_EP1_DMA_CON               S3C2410_USBDREG(0x0200)
++#define S3C2410_UDC_EP1_DMA_UNIT      S3C2410_USBDREG(0x0204)
++#define S3C2410_UDC_EP1_DMA_FIFO      S3C2410_USBDREG(0x0208)
++#define S3C2410_UDC_EP1_DMA_TTC_L     S3C2410_USBDREG(0x020c)
++#define S3C2410_UDC_EP1_DMA_TTC_M     S3C2410_USBDREG(0x0210)
++#define S3C2410_UDC_EP1_DMA_TTC_H     S3C2410_USBDREG(0x0214)
++
++#define S3C2410_UDC_EP2_DMA_CON               S3C2410_USBDREG(0x0218)
++#define S3C2410_UDC_EP2_DMA_UNIT      S3C2410_USBDREG(0x021c)
++#define S3C2410_UDC_EP2_DMA_FIFO      S3C2410_USBDREG(0x0220)
++#define S3C2410_UDC_EP2_DMA_TTC_L     S3C2410_USBDREG(0x0224)
++#define S3C2410_UDC_EP2_DMA_TTC_M     S3C2410_USBDREG(0x0228)
++#define S3C2410_UDC_EP2_DMA_TTC_H     S3C2410_USBDREG(0x022c)
++
++#define S3C2410_UDC_EP3_DMA_CON               S3C2410_USBDREG(0x0240)
++#define S3C2410_UDC_EP3_DMA_UNIT      S3C2410_USBDREG(0x0244)
++#define S3C2410_UDC_EP3_DMA_FIFO      S3C2410_USBDREG(0x0248)
++#define S3C2410_UDC_EP3_DMA_TTC_L     S3C2410_USBDREG(0x024c)
++#define S3C2410_UDC_EP3_DMA_TTC_M     S3C2410_USBDREG(0x0250)
++#define S3C2410_UDC_EP3_DMA_TTC_H     S3C2410_USBDREG(0x0254)
++
++#define S3C2410_UDC_EP4_DMA_CON               S3C2410_USBDREG(0x0258)
++#define S3C2410_UDC_EP4_DMA_UNIT      S3C2410_USBDREG(0x025c)
++#define S3C2410_UDC_EP4_DMA_FIFO      S3C2410_USBDREG(0x0260)
++#define S3C2410_UDC_EP4_DMA_TTC_L     S3C2410_USBDREG(0x0264)
++#define S3C2410_UDC_EP4_DMA_TTC_M     S3C2410_USBDREG(0x0268)
++#define S3C2410_UDC_EP4_DMA_TTC_H     S3C2410_USBDREG(0x026c)
++
++#define S3C2410_UDC_INDEX_REG         S3C2410_USBDREG(0x0178)
++
++/* indexed registers */
++
++#define S3C2410_UDC_MAXP_REG          S3C2410_USBDREG(0x0180)
++
++#define S3C2410_UDC_EP0_CSR_REG               S3C2410_USBDREG(0x0184)
++
++#define S3C2410_UDC_IN_CSR1_REG               S3C2410_USBDREG(0x0184)
++#define S3C2410_UDC_IN_CSR2_REG               S3C2410_USBDREG(0x0188)
++
++#define S3C2410_UDC_OUT_CSR1_REG      S3C2410_USBDREG(0x0190)
++#define S3C2410_UDC_OUT_CSR2_REG      S3C2410_USBDREG(0x0194)
++#define S3C2410_UDC_OUT_FIFO_CNT1_REG S3C2410_USBDREG(0x0198)
++#define S3C2410_UDC_OUT_FIFO_CNT2_REG S3C2410_USBDREG(0x019c)
++
++
++
++#define S3C2410_UDC_PWR_ISOUP         (1<<7) // R/W
++#define S3C2410_UDC_PWR_RESET         (1<<3) // R
++#define S3C2410_UDC_PWR_RESUME                (1<<2) // R/W
++#define S3C2410_UDC_PWR_SUSPEND               (1<<1) // R
++#define S3C2410_UDC_PWR_ENSUSPEND     (1<<0) // R/W
++
++#define S3C2410_UDC_PWR_DEFAULT               0x00
++
++#define S3C2410_UDC_INT_EP4           (1<<4) // R/W (clear only)
++#define S3C2410_UDC_INT_EP3           (1<<3) // R/W (clear only)
++#define S3C2410_UDC_INT_EP2           (1<<2) // R/W (clear only)
++#define S3C2410_UDC_INT_EP1           (1<<1) // R/W (clear only)
++#define S3C2410_UDC_INT_EP0           (1<<0) // R/W (clear only)
++
++#define S3C2410_UDC_USBINT_RESET      (1<<2) // R/W (clear only)
++#define S3C2410_UDC_USBINT_RESUME     (1<<1) // R/W (clear only)
++#define S3C2410_UDC_USBINT_SUSPEND    (1<<0) // R/W (clear only)
++
++#define S3C2410_UDC_INTE_EP4          (1<<4) // R/W
++#define S3C2410_UDC_INTE_EP3          (1<<3) // R/W
++#define S3C2410_UDC_INTE_EP2          (1<<2) // R/W
++#define S3C2410_UDC_INTE_EP1          (1<<1) // R/W
++#define S3C2410_UDC_INTE_EP0          (1<<0) // R/W
++
++#define S3C2410_UDC_USBINTE_RESET     (1<<2) // R/W
++#define S3C2410_UDC_USBINTE_SUSPEND   (1<<0) // R/W
++
++
++#define S3C2410_UDC_INDEX_EP0         (0x00)
++#define S3C2410_UDC_INDEX_EP1         (0x01) // ??
++#define S3C2410_UDC_INDEX_EP2         (0x02) // ??
++#define S3C2410_UDC_INDEX_EP3         (0x03) // ??
++#define S3C2410_UDC_INDEX_EP4         (0x04) // ??
++
++#define S3C2410_UDC_ICSR1_CLRDT               (1<<6) // R/W
++#define S3C2410_UDC_ICSR1_SENTSTL     (1<<5) // R/W (clear only)
++#define S3C2410_UDC_ICSR1_SENDSTL     (1<<4) // R/W
++#define S3C2410_UDC_ICSR1_FFLUSH      (1<<3) // W   (set only)
++#define S3C2410_UDC_ICSR1_UNDRUN      (1<<2) // R/W (clear only)
++#define S3C2410_UDC_ICSR1_PKTRDY      (1<<0) // R/W (set only)
++
++#define S3C2410_UDC_ICSR2_AUTOSET     (1<<7) // R/W
++#define S3C2410_UDC_ICSR2_ISO         (1<<6) // R/W
++#define S3C2410_UDC_ICSR2_MODEIN      (1<<5) // R/W
++#define S3C2410_UDC_ICSR2_DMAIEN      (1<<4) // R/W
++
++#define S3C2410_UDC_OCSR1_CLRDT               (1<<7) // R/W
++#define S3C2410_UDC_OCSR1_SENTSTL     (1<<6) // R/W (clear only)
++#define S3C2410_UDC_OCSR1_SENDSTL     (1<<5) // R/W
++#define S3C2410_UDC_OCSR1_FFLUSH      (1<<4) // R/W
++#define S3C2410_UDC_OCSR1_DERROR      (1<<3) // R
++#define S3C2410_UDC_OCSR1_OVRRUN      (1<<2) // R/W (clear only)
++#define S3C2410_UDC_OCSR1_PKTRDY      (1<<0) // R/W (clear only)
++
++#define S3C2410_UDC_OCSR2_AUTOCLR     (1<<7) // R/W
++#define S3C2410_UDC_OCSR2_ISO         (1<<6) // R/W
++#define S3C2410_UDC_OCSR2_DMAIEN      (1<<5) // R/W
++
++#define S3C2410_UDC_SETIX(X)  writel(X, S3C2410_UDC_INDEX_REG)
++
++#define S3C2410_UDC_EP0_CSR_OPKRDY    (1<<0)
++#define S3C2410_UDC_EP0_CSR_IPKRDY    (1<<1)
++#define S3C2410_UDC_EP0_CSR_SENTSTL   (1<<2)
++#define S3C2410_UDC_EP0_CSR_DE                (1<<3)
++#define S3C2410_UDC_EP0_CSR_SE                (1<<4)
++#define S3C2410_UDC_EP0_CSR_SENDSTL   (1<<5)
++#define S3C2410_UDC_EP0_CSR_SOPKTRDY  (1<<6)
++#define S3C2410_UDC_EP0_CSR_SSE       (1<<7)
++
++#define S3C2410_UDC_MAXP_8            (1<<0)
++#define S3C2410_UDC_MAXP_16           (1<<1)
++#define S3C2410_UDC_MAXP_32           (1<<2)
++#define S3C2410_UDC_MAXP_64           (1<<3)
++
++/****************** MACROS ******************/
++#define BIT_MASK      0xFF
++
++#if 1
++#define maskl(v,m,a)      \
++              writel((readl(a) & ~(m))|((v)&(m)), (a))
++#else
++#define maskl(v,m,a)  do {                                    \
++      unsigned long foo = readl(a);                           \
++      unsigned long bar = (foo & ~(m)) | ((v)&(m));           \
++      serial_printf("0x%08x:0x%x->0x%x\n", (a), foo, bar);    \
++      writel(bar, (a));                                       \
++} while(0)
++#endif
++
++#define clear_ep0_sst() do {                  \
++      S3C2410_UDC_SETIX(0);                   \
++      writel(0x00, S3C2410_UDC_EP0_CSR_REG);  \
++} while(0)
++
++#define clear_ep0_se() do {                           \
++      S3C2410_UDC_SETIX(0);                           \
++      maskl(S3C2410_UDC_EP0_CSR_SSE,                  \
++              BIT_MASK, S3C2410_UDC_EP0_CSR_REG);     \
++} while(0)
++
++#define clear_ep0_opr() do {                          \
++      S3C2410_UDC_SETIX(0);                           \
++      maskl(S3C2410_UDC_EP0_CSR_SOPKTRDY,             \
++              BIT_MASK, S3C2410_UDC_EP0_CSR_REG);     \
++} while(0)
++
++#define set_ep0_ipr() do {                            \
++      S3C2410_UDC_SETIX(0);                           \
++      maskl(S3C2410_UDC_EP0_CSR_IPKRDY,               \
++              BIT_MASK, S3C2410_UDC_EP0_CSR_REG);     \
++} while(0)
++
++#define set_ep0_de() do {                             \
++      S3C2410_UDC_SETIX(0);                           \
++      maskl(S3C2410_UDC_EP0_CSR_DE,                   \
++              BIT_MASK, S3C2410_UDC_EP0_CSR_REG);     \
++} while(0)
++
++#define set_ep0_ss() do {                             \
++      S3C2410_UDC_SETIX(0);                           \
++      maskl(S3C2410_UDC_EP0_CSR_SENDSTL,              \
++              BIT_MASK, S3C2410_UDC_EP0_CSR_REG);     \
++} while(0)
++
++#define set_ep0_de_out() do {                         \
++      S3C2410_UDC_SETIX(0);                           \
++      maskl((S3C2410_UDC_EP0_CSR_SOPKTRDY             \
++              | S3C2410_UDC_EP0_CSR_DE),              \
++              BIT_MASK, S3C2410_UDC_EP0_CSR_REG);     \
++} while(0)
++
++#define set_ep0_sse_out() do {                                \
++      S3C2410_UDC_SETIX(0);                           \
++      maskl((S3C2410_UDC_EP0_CSR_SOPKTRDY             \
++              | S3C2410_UDC_EP0_CSR_SSE),             \
++              BIT_MASK, S3C2410_UDC_EP0_CSR_REG);     \
++} while(0)
++
++#define set_ep0_de_in() do {                          \
++      S3C2410_UDC_SETIX(0);                           \
++      maskl((S3C2410_UDC_EP0_CSR_IPKRDY               \
++              | S3C2410_UDC_EP0_CSR_DE),              \
++              BIT_MASK, S3C2410_UDC_EP0_CSR_REG);     \
++} while(0)
++
++
++#if 0
++
++#define clear_stall_ep1_out(base) do {                        \
++      S3C2410_UDC_SETIX(base,EP1);                    \
++      orl(0,base+S3C2410_UDC_OUT_CSR1_REG);           \
++} while(0)
++
++
++#define clear_stall_ep2_out(base) do {                        \
++      S3C2410_UDC_SETIX(base,EP2);                    \
++      orl(0, base+S3C2410_UDC_OUT_CSR1_REG);          \
++} while(0)
++
++
++#define clear_stall_ep3_out(base) do {                        \
++      S3C2410_UDC_SETIX(base,EP3);                    \
++      orl(0,base+S3C2410_UDC_OUT_CSR1_REG);           \
++} while(0)
++
++
++#define clear_stall_ep4_out(base) do {                        \
++      S3C2410_UDC_SETIX(base,EP4);                    \
++      orl(0, base+S3C2410_UDC_OUT_CSR1_REG);          \
++} while(0)
++
++#endif
++
++/* S3C2410 Endpoint parameters */
++#define EP0_MAX_PACKET_SIZE   16
++#define UDC_OUT_ENDPOINT      2
++#define UDC_OUT_PACKET_SIZE   64
++#define UDC_IN_ENDPOINT               1
++#define UDC_IN_PACKET_SIZE    64
++#define UDC_INT_ENDPOINT      5
++#define UDC_INT_PACKET_SIZE   16
++#define UDC_BULK_PACKET_SIZE  16
++
++#endif
+Index: u-boot/drivers/usbdcore_ep0.c
+===================================================================
+--- u-boot.orig/drivers/usbdcore_ep0.c
++++ u-boot/drivers/usbdcore_ep0.c
+@@ -43,7 +43,7 @@
+ #include <common.h>
+-#if defined(CONFIG_OMAP1510) && defined(CONFIG_USB_DEVICE)
++#if defined(CONFIG_USB_DEVICE)
+ #include "usbdcore.h"
+ #if 0
+@@ -187,9 +187,13 @@
+       if (!urb || !urb->buffer || !urb->buffer_length
+           || (urb->buffer_length < 255)) {
+               dbg_ep0 (2, "invalid urb %p", urb);
++              serial_printf("invalid urb %p", urb);
+               return -1L;
+       }
++      /* re-initialize the ep0 buffer pointer */
++      urb->buffer = (u8 *) urb->buffer_data;
++
+       /* setup tx urb */
+       urb->actual_length = 0;
+       cp = urb->buffer;
+@@ -206,17 +210,8 @@
+                            usbd_device_device_descriptor (device, port))) {
+                               return -1;
+                       }
+-                      /* copy descriptor for this device */
+-                      copy_config (urb, device_descriptor,
+-                                   sizeof (struct usb_device_descriptor),
+-                                   max);
+-
+-                      /* correct the correct control endpoint 0 max packet size into the descriptor */
+-                      device_descriptor =
+-                              (struct usb_device_descriptor *) urb->buffer;
+-                      device_descriptor->bMaxPacketSize0 =
+-                              urb->device->bus->maxpacketsize;
+-
++                      urb->buffer = device_descriptor;
++                      urb->actual_length = MIN(sizeof(*device_descriptor), max);
+               }
+               /*dbg_ep0(3, "copied device configuration, actual_length: %x", urb->actual_length); */
+               break;
+@@ -250,11 +245,9 @@
+                                        index);
+                               return -1;
+                       }
+-                      copy_config (urb, configuration_descriptor,
+-                                   sizeof (struct
+-                                           usb_configuration_descriptor),
+-                                   max);
+-
++                      urb->buffer = configuration_descriptor;
++                      urb->actual_length =
++                              MIN(le16_to_cpu(configuration_descriptor->wTotalLength), max);
+               }
+               break;
+@@ -376,6 +369,7 @@
+       dbg_ep0 (0, "entering ep0_recv_setup()");
+       if (!urb || !urb->device) {
+               dbg_ep0 (3, "invalid URB %p", urb);
++              serial_printf("invalid URB %p", urb);
+               return -1;
+       }
+@@ -400,6 +394,7 @@
+                       return device->cdc_recv_setup(request, urb);
+               dbg_ep0 (1, "non standard request: %x",
+                        request->bmRequestType & USB_REQ_TYPE_MASK);
++              serial_printf("non standard request: %x", request->bmRequestType & USB_REQ_TYPE_MASK);
+               return -1;      /* Stall here */
+       }
+@@ -448,6 +443,8 @@
+               dbg_ep0 (1, "request %s not allowed in UNKNOWN state: %s",
+                        USBD_DEVICE_REQUESTS (request->bRequest),
+                        usbd_device_states[device->device_state]);
++              serial_printf("request %s not allowed in UNKNOWN state: %s", USBD_DEVICE_REQUESTS (request->bRequest), usbd_device_states[device->device_state]);
++              break;
+               return -1;
+       }
+@@ -545,7 +542,8 @@
+                       /*dbg_ep0(2, "address: %d %d %d", */
+                       /*        request->wValue, le16_to_cpu(request->wValue), device->address); */
+-                      serial_printf ("DEVICE_ADDRESS_ASSIGNED.. event?\n");
++                      //serial_printf ("DEVICE_ADDRESS_ASSIGNED.. event?\n");
++                      //udc_set_address(device->address);
+                       return 0;
+               case USB_REQ_SET_DESCRIPTOR:    /* XXX should we support this? */
+Index: u-boot/include/configs/neo1973_gta01.h
+===================================================================
+--- u-boot.orig/include/configs/neo1973_gta01.h
++++ u-boot/include/configs/neo1973_gta01.h
+@@ -173,6 +173,16 @@
+ #define CONFIG_USB_OHCI               1
+ #endif
++#define CONFIG_USB_DEVICE     1
++#define CONFIG_USB_TTY                1
++#define CFG_CONSOLE_IS_IN_ENV 1
++#define CONFIG_USBD_VENDORID          0x1457     /* Linux/NetChip */
++#define CONFIG_USBD_PRODUCTID_GSERIAL 0x5120    /* gserial */
++#define CONFIG_USBD_PRODUCTID_CDCACM  0x5119    /* CDC ACM */
++#define CONFIG_USBD_MANUFACTURER      "OpenMoko, Inc"
++#define CONFIG_USBD_PRODUCT_NAME      "Neo1973 Bootloader " U_BOOT_VERSION
++#define CONFIG_EXTRA_ENV_SETTINGS     "usbtty=cdc_acm\0"
++
+ /*-----------------------------------------------------------------------
+  * Physical Memory Map
+  */
+Index: u-boot/cpu/arm920t/s3c24x0/interrupts.c
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/interrupts.c
++++ u-boot/cpu/arm920t/s3c24x0/interrupts.c
+@@ -222,6 +222,13 @@
+       S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
+       u_int32_t intpnd = irq->INTPND;
++#ifdef CONFIG_USB_DEVICE
++      if (intpnd & BIT_USBD) {
++              s3c2410_udc_irq();
++              irq->SRCPND = BIT_USBD;
++              irq->INTPND = BIT_USBD;
++      }
++#endif /* USB_DEVICE */
+ }
+ #endif /* USE_IRQ */
+Index: u-boot/drivers/usbtty.h
+===================================================================
+--- u-boot.orig/drivers/usbtty.h
++++ u-boot/drivers/usbtty.h
+@@ -29,6 +29,8 @@
+ #include "usbdcore_mpc8xx.h"
+ #elif defined(CONFIG_OMAP1510)
+ #include "usbdcore_omap1510.h"
++#elif defined(CONFIG_S3C2410)
++#include "usbdcore_s3c2410.h"
+ #endif
+ #include <config.h>
+Index: u-boot/board/neo1973/common/cmd_neo1973.c
+===================================================================
+--- u-boot.orig/board/neo1973/common/cmd_neo1973.c
++++ u-boot/board/neo1973/common/cmd_neo1973.c
+@@ -72,6 +72,18 @@
+                       neo1973_vibrator(1);
+               else
+                       neo1973_vibrator(0);
++      } else if (!strcmp(argv[1], "udc")) {
++              if (argc < 3)
++                      goto out_help;
++              if (!strcmp(argv[2], "udc")) {
++                      if (argc < 4)
++                              goto out_help;
++                      if (!strcmp(argv[3], "on"))
++                              udc_connect();
++                      else
++                              udc_disconnect();
++              } else
++                      goto out_help;
+       } else {
+ out_help:
+               printf("Usage:\n%s\n", cmdtp->usage);
+@@ -95,5 +107,6 @@
+       "neo1973 charger off - disable charging\n"
+       "neo1973 backlight (on|off) - switch backlight on or off\n"
+       "neo1973 vibrator (on|off) - switch vibrator on or off\n"
++      "neo1973 udc pullup (on|off) - switch pull-up on or off\n"
+ );
+ #endif        /* CFG_CMD_BDI */
+Index: u-boot/board/neo1973/gta01/Makefile
+===================================================================
+--- u-boot.orig/board/neo1973/gta01/Makefile
++++ u-boot/board/neo1973/gta01/Makefile
+@@ -25,7 +25,7 @@
+ LIB   = lib$(BOARD).a
+-OBJS  := gta01.o pcf50606.o ../common/cmd_neo1973.o ../common/jbt6k74.o
++OBJS  := gta01.o pcf50606.o ../common/cmd_neo1973.o ../common/jbt6k74.o ../common/udc.o
+ SOBJS := ../common/lowlevel_init.o
+ $(LIB):       $(OBJS) $(SOBJS)
+Index: u-boot/board/neo1973/common/udc.c
+===================================================================
+--- /dev/null
++++ u-boot/board/neo1973/common/udc.c
+@@ -0,0 +1,23 @@
++
++#include <common.h>
++#include <usbdcore.h>
++#include <s3c2410.h>
++
++void udc_ctrl(enum usbd_event event, int param)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++      switch (event) {
++      case UDC_CTRL_PULLUP_ENABLE:
++#if defined(CONFIG_ARCH_GTA01_v4) || defined(CONFIG_ARCH_GTA01B_v2) || \
++    defined(CONFIG_ARCH_GTA01B_v3) || defined(CONFIG_ARCH_GTA01B_v4)
++              if (param)
++                      gpio->GPBDAT |= (1 << 9);
++              else
++                      gpio->GPBDAT &= ~(1 << 9);
++#endif
++              break;
++      default:
++              break;
++      }
++}
+Index: u-boot/include/usbdcore.h
+===================================================================
+--- u-boot.orig/include/usbdcore.h
++++ u-boot/include/usbdcore.h
+@@ -671,4 +671,10 @@
+ void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad);
+ void usbd_tx_complete (struct usb_endpoint_instance *endpoint);
++enum usbd_event {
++      UDC_CTRL_PULLUP_ENABLE,
++};
++
++void udc_ctrl(enum usbd_event event, int param);
++#endif
+ #endif
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2440.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2440.patch
new file mode 100644 (file)
index 0000000..da0fb8c
--- /dev/null
@@ -0,0 +1,1301 @@
+Add proper support for S3C2440 CPU's
+
+Index: u-boot/include/s3c24x0.h
+===================================================================
+--- u-boot.orig/include/s3c24x0.h
++++ u-boot/include/s3c24x0.h
+@@ -82,7 +82,7 @@
+       S3C24X0_REG32   PRIORITY;
+       S3C24X0_REG32   INTPND;
+       S3C24X0_REG32   INTOFFSET;
+-#ifdef CONFIG_S3C2410
++#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+       S3C24X0_REG32   SUBSRCPND;
+       S3C24X0_REG32   INTSUBMSK;
+ #endif
+@@ -92,11 +92,11 @@
+ /* DMAS (see manual chapter 8) */
+ typedef struct {
+       S3C24X0_REG32   DISRC;
+-#ifdef CONFIG_S3C2410
++#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+       S3C24X0_REG32   DISRCC;
+ #endif
+       S3C24X0_REG32   DIDST;
+-#ifdef CONFIG_S3C2410
++#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+       S3C24X0_REG32   DIDSTC;
+ #endif
+       S3C24X0_REG32   DCON;
+@@ -107,7 +107,7 @@
+ #ifdef CONFIG_S3C2400
+       S3C24X0_REG32   res[1];
+ #endif
+-#ifdef CONFIG_S3C2410
++#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+       S3C24X0_REG32   res[7];
+ #endif
+ } /*__attribute__((__packed__))*/ S3C24X0_DMA;
+@@ -126,6 +126,9 @@
+       S3C24X0_REG32   CLKCON;
+       S3C24X0_REG32   CLKSLOW;
+       S3C24X0_REG32   CLKDIVN;
++#ifdef CONFIG_S3C2440
++      S3C24X0_REG32   CAMDIVN;
++#endif
+ } /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER;
+@@ -145,7 +148,7 @@
+       S3C24X0_REG32   res[8];
+       S3C24X0_REG32   DITHMODE;
+       S3C24X0_REG32   TPAL;
+-#ifdef CONFIG_S3C2410
++#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+       S3C24X0_REG32   LCDINTPND;
+       S3C24X0_REG32   LCDSRCPND;
+       S3C24X0_REG32   LCDINTMSK;
+@@ -157,6 +160,9 @@
+ /* NAND FLASH (see S3C2410 manual chapter 6) */
+ typedef struct {
+       S3C24X0_REG32   NFCONF;
++#ifdef CONFIG_S3C2440
++      S3C24X0_REG32   NFCONT;
++#endif
+       S3C24X0_REG32   NFCMD;
+       S3C24X0_REG32   NFADDR;
+       S3C24X0_REG32   NFDATA;
+@@ -164,6 +170,15 @@
+       S3C24X0_REG32   NFECC;
+ } /*__attribute__((__packed__))*/ S3C2410_NAND;
++/* NAND FLASH (see S3C2440 manual chapter 6) */
++typedef struct {
++      S3C24X0_REG32   NFCONF;
++      S3C24X0_REG32   NFCMD;
++      S3C24X0_REG32   NFADDR;
++      S3C24X0_REG32   NFDATA;
++      S3C24X0_REG32   NFSTAT;
++      S3C24X0_REG32   NFECC;
++} /*__attribute__((__packed__))*/ S3C2440_NAND;
+ /* UART (see manual chapter 11) */
+ typedef struct {
+@@ -451,6 +466,65 @@
+       S3C24X0_REG32   GSTATUS3;
+       S3C24X0_REG32   GSTATUS4;
+ #endif
++#ifdef CONFIG_S3C2440
++      S3C24X0_REG32   GPACON;
++      S3C24X0_REG32   GPADAT;
++      S3C24X0_REG32   res1[2];
++      S3C24X0_REG32   GPBCON;
++      S3C24X0_REG32   GPBDAT;
++      S3C24X0_REG32   GPBUP;
++      S3C24X0_REG32   res2;
++      S3C24X0_REG32   GPCCON;
++      S3C24X0_REG32   GPCDAT;
++      S3C24X0_REG32   GPCUP;
++      S3C24X0_REG32   res3;
++      S3C24X0_REG32   GPDCON;
++      S3C24X0_REG32   GPDDAT;
++      S3C24X0_REG32   GPDUP;
++      S3C24X0_REG32   res4;
++      S3C24X0_REG32   GPECON;
++      S3C24X0_REG32   GPEDAT;
++      S3C24X0_REG32   GPEUP;
++      S3C24X0_REG32   res5;
++      S3C24X0_REG32   GPFCON;
++      S3C24X0_REG32   GPFDAT;
++      S3C24X0_REG32   GPFUP;
++      S3C24X0_REG32   res6;
++      S3C24X0_REG32   GPGCON;
++      S3C24X0_REG32   GPGDAT;
++      S3C24X0_REG32   GPGUP;
++      S3C24X0_REG32   res7;
++      S3C24X0_REG32   GPHCON;
++      S3C24X0_REG32   GPHDAT;
++      S3C24X0_REG32   GPHUP;
++      S3C24X0_REG32   res8;
++
++      S3C24X0_REG32   MISCCR;
++      S3C24X0_REG32   DCLKCON;
++      S3C24X0_REG32   EXTINT0;
++      S3C24X0_REG32   EXTINT1;
++      S3C24X0_REG32   EXTINT2;
++      S3C24X0_REG32   EINTFLT0;
++      S3C24X0_REG32   EINTFLT1;
++      S3C24X0_REG32   EINTFLT2;
++      S3C24X0_REG32   EINTFLT3;
++      S3C24X0_REG32   EINTMASK;
++      S3C24X0_REG32   EINTPEND;
++      S3C24X0_REG32   GSTATUS0;
++      S3C24X0_REG32   GSTATUS1;
++      S3C24X0_REG32   GSTATUS2;
++      S3C24X0_REG32   GSTATUS3;
++      S3C24X0_REG32   GSTATUS4;
++
++      S3C24X0_REG32   res9;
++      S3C24X0_REG32   DSC0;
++      S3C24X0_REG32   DSC1;
++      S3C24X0_REG32   MSLCON;
++      S3C24X0_REG32   GPJCON;
++      S3C24X0_REG32   GPJDAT;
++      S3C24X0_REG32   GPJUP;
++      S3C24X0_REG32   res10;
++#endif
+ } /*__attribute__((__packed__))*/ S3C24X0_GPIO;
+@@ -637,8 +711,13 @@
+       S3C24X0_REG32   SDIDCNT;
+       S3C24X0_REG32   SDIDSTA;
+       S3C24X0_REG32   SDIFSTA;
++#if defined(CONFIG_S3C2410)
+       S3C24X0_REG32   SDIDAT;
+       S3C24X0_REG32   SDIIMSK;
++#elif defined(CONFIG_S3C2440)
++      S3C24X0_REG32   SDIIMSK;
++      S3C24X0_REG32   SDIDAT;
++#endif
+ } /*__attribute__((__packed__))*/ S3C2410_SDI;
+Index: u-boot/rtc/s3c24x0_rtc.c
+===================================================================
+--- u-boot.orig/rtc/s3c24x0_rtc.c
++++ u-boot/rtc/s3c24x0_rtc.c
+@@ -34,6 +34,8 @@
+ #include <s3c2400.h>
+ #elif defined(CONFIG_S3C2410)
+ #include <s3c2410.h>
++#elif defined(CONFIG_S3C2440)
++#include <s3c2440.h>
+ #endif
+ #include <rtc.h>
+Index: u-boot/include/s3c2440.h
+===================================================================
+--- /dev/null
++++ u-boot/include/s3c2440.h
+@@ -0,0 +1,300 @@
++/*
++ * (C) Copyright 2003
++ * David Müller ELSOFT AG Switzerland. d.mueller@elsoft.ch
++ *
++ * 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
++ */
++
++/************************************************
++ * NAME           : s3c2440.h
++ * Version  : 2007.
++ *
++ * Based on S3C2410X User's manual Rev 1.1
++ ************************************************/
++
++#ifndef __S3C2440_H__
++#define __S3C2440_H__
++
++#define S3C24X0_UART_CHANNELS 3
++#define S3C24X0_SPI_CHANNELS  2
++
++/* S3C2440 only supports 512 Byte HW ECC */
++#define S3C2440_ECCSIZE               512
++#define S3C2440_ECCBYTES      3
++
++/* S3C2440 device base addresses */
++#define S3C24X0_MEMCTL_BASE           0x48000000
++#define S3C24X0_USB_HOST_BASE         0x49000000
++#define S3C24X0_INTERRUPT_BASE                0x4A000000
++#define S3C24X0_DMA_BASE              0x4B000000
++#define S3C24X0_CLOCK_POWER_BASE      0x4C000000
++#define S3C24X0_LCD_BASE              0x4D000000
++#define S3C2440_NAND_BASE             0x4E000000
++#define S3C24X0_UART_BASE             0x50000000
++#define S3C24X0_TIMER_BASE            0x51000000
++#define S3C24X0_USB_DEVICE_BASE               0x52000140
++#define USB_DEVICE_PHYS_ADR           0x52000000
++#define S3C24X0_WATCHDOG_BASE         0x53000000
++#define S3C24X0_I2C_BASE              0x54000000
++#define S3C24X0_I2S_BASE              0x55000000
++#define S3C24X0_GPIO_BASE             0x56000000
++#define S3C24X0_RTC_BASE              0x57000000
++#define S3C2440_ADC_BASE              0x58000000
++#define S3C24X0_SPI_BASE              0x59000000
++#define S3C2440_SDI_BASE              0x5A000000
++
++#define oNFCONF                       0x00
++#define oNFCONT                       0x04
++
++#ifndef __ASSEMBLER__
++
++/* include common stuff */
++#include <s3c24x0.h>
++
++typedef enum {
++      S3C24X0_UART0,
++      S3C24X0_UART1,
++      S3C24X0_UART2
++} S3C24X0_UARTS_NR;
++
++static inline S3C24X0_MEMCTL * S3C24X0_GetBase_MEMCTL(void)
++{
++      return (S3C24X0_MEMCTL * const)S3C24X0_MEMCTL_BASE;
++}
++static inline S3C24X0_USB_HOST * S3C24X0_GetBase_USB_HOST(void)
++{
++      return (S3C24X0_USB_HOST * const)S3C24X0_USB_HOST_BASE;
++}
++static inline S3C24X0_INTERRUPT * S3C24X0_GetBase_INTERRUPT(void)
++{
++      return (S3C24X0_INTERRUPT * const)S3C24X0_INTERRUPT_BASE;
++}
++static inline S3C24X0_DMAS * S3C24X0_GetBase_DMAS(void)
++{
++      return (S3C24X0_DMAS * const)S3C24X0_DMA_BASE;
++}
++static inline S3C24X0_CLOCK_POWER * S3C24X0_GetBase_CLOCK_POWER(void)
++{
++      return (S3C24X0_CLOCK_POWER * const)S3C24X0_CLOCK_POWER_BASE;
++}
++static inline S3C24X0_LCD * S3C24X0_GetBase_LCD(void)
++{
++      return (S3C24X0_LCD * const)S3C24X0_LCD_BASE;
++}
++static inline S3C2440_NAND * S3C2440_GetBase_NAND(void)
++{
++      return (S3C2440_NAND * const)S3C2440_NAND_BASE;
++}
++static inline S3C24X0_UART * S3C24X0_GetBase_UART(S3C24X0_UARTS_NR nr)
++{
++      return (S3C24X0_UART * const)(S3C24X0_UART_BASE + (nr * 0x4000));
++}
++static inline S3C24X0_TIMERS * S3C24X0_GetBase_TIMERS(void)
++{
++      return (S3C24X0_TIMERS * const)S3C24X0_TIMER_BASE;
++}
++static inline S3C24X0_USB_DEVICE * S3C24X0_GetBase_USB_DEVICE(void)
++{
++      return (S3C24X0_USB_DEVICE * const)S3C24X0_USB_DEVICE_BASE;
++}
++static inline S3C24X0_WATCHDOG * S3C24X0_GetBase_WATCHDOG(void)
++{
++      return (S3C24X0_WATCHDOG * const)S3C24X0_WATCHDOG_BASE;
++}
++static inline S3C24X0_I2C * S3C24X0_GetBase_I2C(void)
++{
++      return (S3C24X0_I2C * const)S3C24X0_I2C_BASE;
++}
++static inline S3C24X0_I2S * S3C24X0_GetBase_I2S(void)
++{
++      return (S3C24X0_I2S * const)S3C24X0_I2S_BASE;
++}
++static inline S3C24X0_GPIO * S3C24X0_GetBase_GPIO(void)
++{
++      return (S3C24X0_GPIO * const)S3C24X0_GPIO_BASE;
++}
++static inline S3C24X0_RTC * S3C24X0_GetBase_RTC(void)
++{
++      return (S3C24X0_RTC * const)S3C24X0_RTC_BASE;
++}
++/*
++static inline S3C2440_ADC * S3C2440_GetBase_ADC(void)
++{
++      return (S3C2440_ADC * const)S3C2440_ADC_BASE;
++}
++static inline S3C24X0_SPI * S3C24X0_GetBase_SPI(void)
++{
++      return (S3C24X0_SPI * const)S3C24X0_SPI_BASE;
++}
++*/
++static inline S3C2410_SDI * S3C2410_GetBase_SDI(void)
++{
++      return (S3C2410_SDI * const)S3C2440_SDI_BASE;
++}
++
++#endif /* __ASSEMBLER__ */
++
++/* ISR */
++#define pISR_RESET            (*(unsigned *)(_ISR_STARTADDRESS+0x0))
++#define pISR_UNDEF            (*(unsigned *)(_ISR_STARTADDRESS+0x4))
++#define pISR_SWI              (*(unsigned *)(_ISR_STARTADDRESS+0x8))
++#define pISR_PABORT           (*(unsigned *)(_ISR_STARTADDRESS+0xC))
++#define pISR_DABORT           (*(unsigned *)(_ISR_STARTADDRESS+0x10))
++#define pISR_RESERVED         (*(unsigned *)(_ISR_STARTADDRESS+0x14))
++#define pISR_IRQ              (*(unsigned *)(_ISR_STARTADDRESS+0x18))
++#define pISR_FIQ              (*(unsigned *)(_ISR_STARTADDRESS+0x1C))
++
++#define pISR_EINT0            (*(unsigned *)(_ISR_STARTADDRESS+0x20))
++#define pISR_EINT1            (*(unsigned *)(_ISR_STARTADDRESS+0x24))
++#define pISR_EINT2            (*(unsigned *)(_ISR_STARTADDRESS+0x28))
++#define pISR_EINT3            (*(unsigned *)(_ISR_STARTADDRESS+0x2C))
++#define pISR_EINT4_7          (*(unsigned *)(_ISR_STARTADDRESS+0x30))
++#define pISR_EINT8_23         (*(unsigned *)(_ISR_STARTADDRESS+0x34))
++#define pISR_BAT_FLT          (*(unsigned *)(_ISR_STARTADDRESS+0x3C))
++#define pISR_TICK             (*(unsigned *)(_ISR_STARTADDRESS+0x40))
++#define pISR_WDT              (*(unsigned *)(_ISR_STARTADDRESS+0x44))
++#define pISR_TIMER0           (*(unsigned *)(_ISR_STARTADDRESS+0x48))
++#define pISR_TIMER1           (*(unsigned *)(_ISR_STARTADDRESS+0x4C))
++#define pISR_TIMER2           (*(unsigned *)(_ISR_STARTADDRESS+0x50))
++#define pISR_TIMER3           (*(unsigned *)(_ISR_STARTADDRESS+0x54))
++#define pISR_TIMER4           (*(unsigned *)(_ISR_STARTADDRESS+0x58))
++#define pISR_UART2            (*(unsigned *)(_ISR_STARTADDRESS+0x5C))
++#define pISR_NOTUSED          (*(unsigned *)(_ISR_STARTADDRESS+0x60))
++#define pISR_DMA0             (*(unsigned *)(_ISR_STARTADDRESS+0x64))
++#define pISR_DMA1             (*(unsigned *)(_ISR_STARTADDRESS+0x68))
++#define pISR_DMA2             (*(unsigned *)(_ISR_STARTADDRESS+0x6C))
++#define pISR_DMA3             (*(unsigned *)(_ISR_STARTADDRESS+0x70))
++#define pISR_SDI              (*(unsigned *)(_ISR_STARTADDRESS+0x74))
++#define pISR_SPI0             (*(unsigned *)(_ISR_STARTADDRESS+0x78))
++#define pISR_UART1            (*(unsigned *)(_ISR_STARTADDRESS+0x7C))
++#define pISR_USBD             (*(unsigned *)(_ISR_STARTADDRESS+0x84))
++#define pISR_USBH             (*(unsigned *)(_ISR_STARTADDRESS+0x88))
++#define pISR_IIC              (*(unsigned *)(_ISR_STARTADDRESS+0x8C))
++#define pISR_UART0            (*(unsigned *)(_ISR_STARTADDRESS+0x90))
++#define pISR_SPI1             (*(unsigned *)(_ISR_STARTADDRESS+0x94))
++#define pISR_RTC              (*(unsigned *)(_ISR_STARTADDRESS+0x98))
++#define pISR_ADC              (*(unsigned *)(_ISR_STARTADDRESS+0xA0))
++
++
++/* PENDING BIT */
++#define BIT_EINT0             (0x1)
++#define BIT_EINT1             (0x1<<1)
++#define BIT_EINT2             (0x1<<2)
++#define BIT_EINT3             (0x1<<3)
++#define BIT_EINT4_7           (0x1<<4)
++#define BIT_EINT8_23          (0x1<<5)
++#define BIT_BAT_FLT           (0x1<<7)
++#define BIT_TICK              (0x1<<8)
++#define BIT_WDT                       (0x1<<9)
++#define BIT_TIMER0            (0x1<<10)
++#define BIT_TIMER1            (0x1<<11)
++#define BIT_TIMER2            (0x1<<12)
++#define BIT_TIMER3            (0x1<<13)
++#define BIT_TIMER4            (0x1<<14)
++#define BIT_UART2             (0x1<<15)
++#define BIT_LCD                       (0x1<<16)
++#define BIT_DMA0              (0x1<<17)
++#define BIT_DMA1              (0x1<<18)
++#define BIT_DMA2              (0x1<<19)
++#define BIT_DMA3              (0x1<<20)
++#define BIT_SDI                       (0x1<<21)
++#define BIT_SPI0              (0x1<<22)
++#define BIT_UART1             (0x1<<23)
++#define BIT_USBD              (0x1<<25)
++#define BIT_USBH              (0x1<<26)
++#define BIT_IIC                       (0x1<<27)
++#define BIT_UART0             (0x1<<28)
++#define BIT_SPI1              (0x1<<29)
++#define BIT_RTC                       (0x1<<30)
++#define BIT_ADC                       (0x1<<31)
++#define BIT_ALLMSK            (0xFFFFFFFF)
++
++#define ClearPending(bit) {\
++               rSRCPND = bit;\
++               rINTPND = bit;\
++               rINTPND;\
++               }
++/* Wait until rINTPND is changed for the case that the ISR is very short. */
++
++#define __REG(x)      (*(volatile unsigned long *)(x))
++#define __REGl(x)     (*(volatile unsigned long *)(x))
++#define __REGw(x)     (*(volatile unsigned short *)(x))
++#define __REGb(x)     (*(volatile unsigned char *)(x))
++#define __REG2(x,y)   (*(volatile unsigned long *)((x) + (y)))
++
++/*
++ *  * Nand flash controller
++ *   */
++
++#define NFDATA8                       (*(volatile unsigned char *)0x4E000010)
++#define NFDATA16              (*(volatile unsigned short *)0x4E000010)
++#define NFDATA32              (*(volatile unsigned *)0x4E000010)
++
++#define NFCONF                  __REG(0x4E000000)
++#define NFCONT                  __REG(0x4E000004)
++#define NFCMD                  __REG(0x4E000008)
++#define NFADDR                  __REGb(0x4E00000C)
++#define NFMECCD0                __REG(0x4E000014)
++#define NFMECCD1                __REG(0x4E000018)
++#define NFSECCD                 __REG(0x4E00001C)
++#define NFSTAT                  __REG(0x4E000020)
++#define NFESTAT0                __REG(0x4E000024)
++#define NFESTAT1                __REG(0x4E000028)
++#define NFMECC0                 __REG(0x4E00002C)
++#define NFMECC1                 __REG(0x4E000030)
++#define NFSECC                  __REG(0x4E000034)
++#define NFSBLK                  __REG(0x4E000038)
++
++
++#define S3C2410_MISCCR_USBDEV     (0<<3)
++#define S3C2410_MISCCR_USBHOST            (1<<3)
++
++#define S3C2410_MISCCR_CLK0_MPLL    (0<<4)
++#define S3C2410_MISCCR_CLK0_UPLL    (1<<4)
++#define S3C2410_MISCCR_CLK0_FCLK    (2<<4)
++#define S3C2410_MISCCR_CLK0_HCLK    (3<<4)
++#define S3C2410_MISCCR_CLK0_PCLK    (4<<4)
++#define S3C2410_MISCCR_CLK0_DCLK0   (5<<4)
++#define S3C2410_MISCCR_CLK0_MASK    (7<<4)
++
++#define S3C2410_MISCCR_CLK1_MPLL    (0<<8)
++#define S3C2410_MISCCR_CLK1_UPLL    (1<<8)
++#define S3C2410_MISCCR_CLK1_FCLK    (2<<8)
++#define S3C2410_MISCCR_CLK1_HCLK    (3<<8)
++#define S3C2410_MISCCR_CLK1_PCLK    (4<<8)
++#define S3C2410_MISCCR_CLK1_DCLK1   (5<<8)
++#define S3C2410_MISCCR_CLK1_MASK    (7<<8)
++
++#define S3C2410_MISCCR_USBSUSPND0   (1<<12)
++#define S3C2410_MISCCR_USBSUSPND1   (1<<13)
++
++#define S3C2410_MISCCR_nRSTCON            (1<<16)
++
++#define S3C2410_MISCCR_nEN_SCLK0    (1<<17)
++#define S3C2410_MISCCR_nEN_SCLK1    (1<<18)
++#define S3C2410_MISCCR_nEN_SCLKE    (1<<19)
++#define S3C2410_MISCCR_SDSLEEP            (7<<17)
++
++#define S3C2410_CLKSLOW_UCLK_OFF      (1<<7)
++#define S3C2410_CLKSLOW_MPLL_OFF      (1<<5)
++#define S3C2410_CLKSLOW_SLOW          (1<<4)
++#define S3C2410_CLKSLOW_SLOWVAL(x)    (x)
++#define S3C2410_CLKSLOW_GET_SLOWVAL(x)        ((x) & 7)
++
++#endif /*__S3C2440_H__*/
+Index: u-boot/include/common.h
+===================================================================
+--- u-boot.orig/include/common.h
++++ u-boot/include/common.h
+@@ -454,7 +454,7 @@
+ ulong get_OPB_freq (void);
+ ulong get_PCI_freq (void);
+ #endif
+-#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_LH7A40X)
++#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined(CONFIG_LH7A40X)
+ void  s3c2410_irq(void);
+ #define ARM920_IRQ_CALLBACK s3c2410_irq
+ ulong get_FCLK (void);
+Index: u-boot/cpu/arm920t/s3c24x0/usb_ohci.c
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/usb_ohci.c
++++ u-boot/cpu/arm920t/s3c24x0/usb_ohci.c
+@@ -44,6 +44,8 @@
+ #include <s3c2400.h>
+ #elif defined(CONFIG_S3C2410)
+ #include <s3c2410.h>
++#elif defined(CONFIG_S3C2440)
++#include <s3c2440.h>
+ #endif
+ #include <malloc.h>
+Index: u-boot/cpu/arm920t/s3c24x0/speed.c
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/speed.c
++++ u-boot/cpu/arm920t/s3c24x0/speed.c
+@@ -30,12 +30,15 @@
+  */
+ #include <common.h>
+-#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB)
++#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || \
++    defined (CONFIG_S3C2440) || defined (CONFIG_TRAB)
+ #if defined(CONFIG_S3C2400)
+ #include <s3c2400.h>
+ #elif defined(CONFIG_S3C2410)
+ #include <s3c2410.h>
++#elif defined(CONFIG_S3C2440)
++#include <s3c2440.h>
+ #endif
+ #define MPLL 0
+@@ -66,8 +69,12 @@
+     m = ((r & 0xFF000) >> 12) + 8;
+     p = ((r & 0x003F0) >> 4) + 2;
+     s = r & 0x3;
+-
++#ifndef CONFIG_S3C2440
+     return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
++#else
++    /* To avoid integer overflow, changed the calc order */
++    return( 2 * m * (CONFIG_SYS_CLK_FREQ / (p << s )) );
++#endif
+ }
+ /* return FCLK frequency */
+@@ -81,7 +88,21 @@
+ {
+     S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
++#ifndef CONFIG_S3C2440
+     return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
++#else
++    switch (clk_power->CLKDIVN & 0x6) {
++        case 0x0:
++          return get_FCLK();
++      case 0x2:
++          return get_FCLK()/2;
++      case 0x4:
++          return (clk_power->CAMDIVN & 0x200) ? get_FCLK()/8 : get_FCLK()/4;
++      case 0x6:
++          return (clk_power->CAMDIVN & 0x100) ? get_FCLK()/6 : get_FCLK()/3;
++    }
++    return 0;
++#endif
+ }
+ /* return PCLK frequency */
+@@ -98,4 +119,5 @@
+     return(get_PLLCLK(UPLL));
+ }
+-#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) */
++#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) ||
++          defined(CONFIG_S3C2440) || defined (CONFIG_TRAB) */
+Index: u-boot/cpu/arm920t/s3c24x0/interrupts.c
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/interrupts.c
++++ u-boot/cpu/arm920t/s3c24x0/interrupts.c
+@@ -30,13 +30,16 @@
+  */
+ #include <common.h>
+-#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB)
++#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || \
++    defined(CONFIG_S3C2440) || defined (CONFIG_TRAB)
+ #include <arm920t.h>
+ #if defined(CONFIG_S3C2400)
+ #include <s3c2400.h>
+ #elif defined(CONFIG_S3C2410)
+ #include <s3c2410.h>
++#elif defined(CONFIG_S3C2440)
++#include <s3c2440.h>
+ #endif
+ int timer_load_val = 0;
+@@ -59,6 +62,7 @@
+       /* use PWM Timer 4 because it has no output */
+       /* prescaler for Timer 4 is 16 */
+       timers->TCFG0 = 0x0f00;
++#ifndef CONFIG_S3C2440
+       if (timer_load_val == 0)
+       {
+               /*
+@@ -68,6 +72,9 @@
+                */
+               timer_load_val = get_PCLK()/(2 * 16 * 100);
+       }
++#else
++      timer_load_val = get_PCLK()/(2 * 16 * 100);
++#endif
+       /* load value for 10 ms timeout */
+       lastdec = timers->TCNTB4 = timer_load_val;
+       /* auto load, manual update of Timer 4 */
+@@ -178,6 +185,7 @@
+       tbclk = timer_load_val * 100;
+ #elif defined(CONFIG_SBC2410X) || \
+       defined(CONFIG_SMDK2410) || \
++      defined(CONFIG_SMDK2440) || \
+       defined(CONFIG_VCMA9)
+       tbclk = CFG_HZ;
+ #else
+@@ -232,4 +240,5 @@
+ }
+ #endif /* USE_IRQ */
+-#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) */
++#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) ||
++        defined(CONFIG_S3C2440) || defined (CONFIG_TRAB) */
+Index: u-boot/cpu/arm920t/s3c24x0/serial.c
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/serial.c
++++ u-boot/cpu/arm920t/s3c24x0/serial.c
+@@ -19,12 +19,15 @@
+  */
+ #include <common.h>
+-#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB)
++#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || \
++    defined(CONFIG_S3C2440) || defined (CONFIG_TRAB)
+ #if defined(CONFIG_S3C2400) || defined(CONFIG_TRAB)
+ #include <s3c2400.h>
+ #elif defined(CONFIG_S3C2410)
+ #include <s3c2410.h>
++#elif defined(CONFIG_S3C2440)
++#include <s3c2440.h>
+ #endif
+ DECLARE_GLOBAL_DATA_PTR;
+@@ -180,4 +183,5 @@
+       }
+ }
+-#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) */
++#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) ||
++        defined(CONFIG_S3C2440) || defined (CONFIG_TRAB) */
+Index: u-boot/cpu/arm920t/s3c24x0/i2c.c
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/i2c.c
++++ u-boot/cpu/arm920t/s3c24x0/i2c.c
+@@ -34,6 +34,8 @@
+ #include <s3c2400.h>
+ #elif defined(CONFIG_S3C2410)
+ #include <s3c2410.h>
++#elif defined(CONFIG_S3C2440)
++#include <s3c2440.h>
+ #endif
+ #include <i2c.h>
+@@ -63,7 +65,7 @@
+ {
+       S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+-#ifdef CONFIG_S3C2410
++#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+       return (gpio->GPEDAT & 0x8000) >> 15;
+ #endif
+ #ifdef CONFIG_S3C2400
+@@ -82,7 +84,7 @@
+ {
+       S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+-#ifdef CONFIG_S3C2410
++#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+       gpio->GPEDAT = (gpio->GPEDAT & ~0x4000) | (x&1) << 14;
+ #endif
+ #ifdef CONFIG_S3C2400
+@@ -139,7 +141,7 @@
+       }
+       if ((status & I2CSTAT_BSY) || GetI2CSDA () == 0) {
+-#ifdef CONFIG_S3C2410
++#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+               ulong old_gpecon = gpio->GPECON;
+ #endif
+ #ifdef CONFIG_S3C2400
+@@ -147,7 +149,7 @@
+ #endif
+               /* bus still busy probably by (most) previously interrupted transfer */
+-#ifdef CONFIG_S3C2410
++#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+               /* set I2CSDA and I2CSCL (GPE15, GPE14) to GPIO */
+               gpio->GPECON = (gpio->GPECON & ~0xF0000000) | 0x10000000;
+ #endif
+@@ -171,7 +173,7 @@
+               udelay (1000);
+               /* restore pin functions */
+-#ifdef CONFIG_S3C2410
++#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+               gpio->GPECON = old_gpecon;
+ #endif
+ #ifdef CONFIG_S3C2400
+Index: u-boot/drivers/usbdcore_s3c2410.c
+===================================================================
+--- u-boot.orig/drivers/usbdcore_s3c2410.c
++++ u-boot/drivers/usbdcore_s3c2410.c
+@@ -24,7 +24,7 @@
+ #include <config.h>
+-#if defined(CONFIG_S3C2410) && defined(CONFIG_USB_DEVICE)
++#if (defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)) && defined(CONFIG_USB_DEVICE)
+ #include <common.h>
+Index: u-boot/drivers/usbtty.h
+===================================================================
+--- u-boot.orig/drivers/usbtty.h
++++ u-boot/drivers/usbtty.h
+@@ -29,7 +29,7 @@
+ #include "usbdcore_mpc8xx.h"
+ #elif defined(CONFIG_OMAP1510)
+ #include "usbdcore_omap1510.h"
+-#elif defined(CONFIG_S3C2410)
++#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+ #include "usbdcore_s3c2410.h"
+ #endif
+Index: u-boot/cpu/arm920t/start.S
+===================================================================
+--- u-boot.orig/cpu/arm920t/start.S
++++ u-boot/cpu/arm920t/start.S
+@@ -31,7 +31,11 @@
+ #include <config.h>
+ #include <version.h>
++#if defined(CONFIG_S3C2410)
+ #include <s3c2410.h>
++#elif defined(CONFIG_S3C2440)
++#include <s3c2440.h>
++#endif
+ /*
+@@ -142,14 +146,32 @@
+ # define pWTCON               0x15300000
+ # define INTMSK               0x14400008      /* Interupt-Controller base addresses */
+ # define CLKDIVN      0x14800014      /* clock divisor register */
+-#elif defined(CONFIG_S3C2410)
++#elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
+ # define pWTCON               0x53000000
+ # define INTMSK               0x4A000008      /* Interupt-Controller base addresses */
+ # define INTSUBMSK    0x4A00001C
+ # define CLKDIVN      0x4C000014      /* clock divisor register */
+ #endif
+-#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
++#if defined(CONFIG_S3C2410)
++# define INTSUBMSK_val        0x7ff
++# define MPLLCON_val  ((0x90 << 12) + (0x7 << 4) + 0x0)       /* 202 MHz */
++# define UPLLCON_val  ((0x78 << 12) + (0x2 << 4) + 0x3)
++# define CLKDIVN_val  3 /* FCLK:HCLK:PCLK = 1:2:4 */
++#elif defined(CONFIG_S3C2440)
++# define INTSUBMSK_val        0xffff
++#if (CONFIG_SYS_CLK_FREQ == 16934400)
++# define MPLLCON_val  ((0x61 << 12) + (0x1 << 4) + 0x2)       /* 296.35 MHz */
++# define UPLLCON_val  ((0x3c << 12) + (0x4 << 4) + 0x2)       /*  47.98 MHz */
++#else if (CONFIG_SYS_CLK_FREQ == 12000000)
++# define MPLLCON_val  ((0x44 << 12) + (0x1 << 4) + 0x1)       /* 304.00 MHz */
++# define UPLLCON_val  ((0x38 << 12) + (0x2 << 4) + 0x2)       /*  48.00 MHz */
++#endif
++# define CLKDIVN_val  7 /* FCLK:HCLK:PCLK = 1:3:6 */
++# define CAMDIVN      0x4C000018
++#endif
++
++#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+       ldr     r0, =pWTCON
+       mov     r1, #0x0
+       str     r1, [r0]
+@@ -160,24 +182,34 @@
+       mov     r1, #0xffffffff
+       ldr     r0, =INTMSK
+       str     r1, [r0]
+-# if defined(CONFIG_S3C2410)
+-      ldr     r1, =0x3ff
++# if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
++      ldr     r1, =INTSUBMSK_val
+       ldr     r0, =INTSUBMSK
+       str     r1, [r0]
+ # endif
+-      /* default FCLK is 202 MHz ! */
++#if defined(CONFIG_S3C2440)
++      /* Make sure we get FCLK:HCLK:PCLK = 1:3:6 */
++      ldr     r0, =CAMDIVN
++      mov     r1, #0
++      str     r1, [r0]
++#endif
++
++      /* Clock asynchronous mode */
++      mrc     p15, 0, r1, c1, c0, 0
++      orr     r1, r1, #0xc0000000
++      mcr     p15, 0, r1, c1, c0, 0
++
++
+ #define LOCKTIME      0x4c000000
+ #define UPLLCON               0x4c000008
+-//#define MPLLCFG             ((0x90 << 12) + (0x2 << 4) + 0x2)
+-#define MPLLCFG               ((0x90 << 12) + (0x7 << 4) + 0x0)
+-#define UPLLCFG               ((0x78 << 12) + (0x2 << 4) + 0x3)
++
+       ldr     r0, =LOCKTIME
+       mov     r1, #0xffffff
+       str     r1, [r0]
+       ldr     r0, =UPLLCON
+-      ldr     r1, =UPLLCFG
++      ldr     r1, =UPLLCON_val
+       str     r1, [r0]
+       /* Page 7-19, seven nops between UPLL and MPLL */
+@@ -189,12 +221,12 @@
+       nop
+       nop
+-      ldr     r1, =MPLLCFG
++      ldr     r1, =MPLLCON_val
+       str     r1, [r0, #-4]           /* MPLLCON */
+       /* FCLK:HCLK:PCLK = 1:2:4 */
+       ldr     r0, =CLKDIVN
+-      mov     r1, #3
++      mov     r1, #CLKDIVN_val
+       str     r1, [r0]
+ #if 1
+@@ -222,7 +254,7 @@
+       str     r1, [r0, #0x28]
+ #endif
+-#endif        /* CONFIG_S3C2400 || CONFIG_S3C2410 */
++#endif        /* CONFIG_S3C2400 || CONFIG_S3C2410 || CONFIG_S3C2440 */
+ #ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ #ifndef CONFIG_LL_INIT_NAND_ONLY
+@@ -279,7 +311,7 @@
+ #if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && defined(CONFIG_LL_INIT_NAND_ONLY)
+       bl      cpu_init_crit
+ #endif
+-#if defined(CONFIG_S3C2410)
++#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+       /* ensure some refresh has happened */
+       ldr     r1, =0xfffff
+ 1:    subs    r1, r1, #1
+@@ -290,11 +322,12 @@
+       ldr     r0, [ r1 ]
+       tst     r0, #0x02               /* is this resume from power down */
+       ldrne   pc, [r1, #4]            /* gstatus3 */
+-#endif /* CONFIG_S3C2410 */
++#endif /* CONFIG_S3C2410 || CONFIG_S3C2440 */
+ #endif /* CONFIG_SKIP_LOWLEVEL_INIT */
+       /* mov  r10, lr */
++#if defined(CONFIG_S3C2410)
+       @ reset NAND
+       mov     r1, #S3C2410_NAND_BASE
+       ldr     r2, =0xf842             @ initial value enable tacls=3,rph0=6,rph1=0
+@@ -314,6 +347,17 @@
+       ldr     r2, [r1, #oNFCONF]
+       orr     r2, r2, #0x800          @ disable chip
+       str     r2, [r1, #oNFCONF]
++#elif defined(CONFIG_S3C2440)
++      mov     r1, #S3C2440_NAND_BASE
++      ldr     r2, =0xfff0             @ initial value tacls=3,rph0=7,rph1=7
++      ldr     r3, [r1, #oNFCONF]
++      orr     r3, r3, r2
++      str     r3, [r1, #oNFCONF]
++
++      ldr     r3, [r1, #oNFCONT]
++      orr     r3, r3, #1              @ enable nand controller
++      str     r3, [r1, #oNFCONT]
++#endif
+ #if 0
+       @ get ready to call C functions (for nand_read())
+@@ -382,7 +426,7 @@
+ #endif /* CONFIG_S3C2410_NAND_BOOT */
+ done_relocate:
+-#if defined(CONFIG_USE_IRQ) && defined(CONFIG_S3C2410)
++#if defined(CONFIG_USE_IRQ) && (defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440))
+       /* In the case of the S3C2410, if we've somehow magically (JTAG, ...)
+          ended up in RAM, then that ram is mapped to 0x30000000 and not 0.
+          So we need to copy the interrupt vectors, etc.  */
+Index: u-boot/cpu/arm920t/s3c24x0/nand_read.c
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/nand_read.c
++++ u-boot/cpu/arm920t/s3c24x0/nand_read.c
+@@ -16,30 +16,141 @@
+  */
+ #include <common.h>
++#include <linux/mtd/nand.h>
+ #ifdef CONFIG_S3C2410_NAND_BOOT
+ #define __REGb(x)     (*(volatile unsigned char *)(x))
++#define __REGw(x)     (*(volatile unsigned short *)(x))
+ #define __REGi(x)     (*(volatile unsigned int *)(x))
+ #define NF_BASE               0x4e000000
++#if defined(CONFIG_S3C2410)
+ #define NFCONF                __REGi(NF_BASE + 0x0)
+ #define NFCMD         __REGb(NF_BASE + 0x4)
+ #define NFADDR                __REGb(NF_BASE + 0x8)
+ #define NFDATA                __REGb(NF_BASE + 0xc)
+ #define NFSTAT                __REGb(NF_BASE + 0x10)
++#define NFSTAT_BUSY   1
++#define nand_select() (NFCONF &= ~0x800)
++#define nand_deselect()       (NFCONF |= 0x800)
++#define nand_clear_RnB()      do {} while (0)
++#elif defined(CONFIG_S3C2440)
++#define NFCONF                __REGi(NF_BASE + 0x0)
++#define NFCONT                __REGi(NF_BASE + 0x4)
++#define NFCMD         __REGb(NF_BASE + 0x8)
++#define NFADDR                __REGb(NF_BASE + 0xc)
++#define NFDATA                __REGb(NF_BASE + 0x10)
++#define NFDATA16      __REGw(NF_BASE + 0x10)
++#define NFSTAT                __REGb(NF_BASE + 0x20)
++#define NFSTAT_BUSY   1
++#define nand_select() (NFCONT &= ~(1 << 1))
++#define nand_deselect()       (NFCONT |= (1 << 1))
++#define nand_clear_RnB()      (NFSTAT |= (1 << 2))
++#endif
+-#define BUSY 1
+-inline void wait_idle(void)
++static inline void nand_wait(void)
+ {
+       int i;
+-      while (!(NFSTAT & BUSY))
++      while (!(NFSTAT & NFSTAT_BUSY))
+               for (i=0; i<10; i++);
+ }
+-#define NAND_SECTOR_SIZE      512
+-#define NAND_BLOCK_MASK               (NAND_SECTOR_SIZE - 1)
+-#define NAND_PAGE_SIZE                0x4000
++#if defined(CONFIG_S3C2410)
++/* configuration for 2410 with 512byte sized flash */
++#define NAND_PAGE_SIZE                512
++#define BAD_BLOCK_OFFSET      517
++#define NAND_BLOCK_MASK               (NAND_PAGE_SIZE - 1)
++#define NAND_BLOCK_SIZE               0x4000
++#else
++/* configuration for 2440 with 2048byte sized flash */
++#define NAND_5_ADDR_CYCLE
++#define NAND_PAGE_SIZE                2048
++#define BAD_BLOCK_OFFSET      NAND_PAGE_SIZE
++#define       NAND_BLOCK_MASK         (NAND_PAGE_SIZE - 1)
++#define NAND_BLOCK_SIZE               (NAND_PAGE_SIZE * 64)
++#endif
++
++/* compile time failure in case of an invalid configuration */
++#if defined(CONFIG_S3C2410) && (NAND_PAGE_SIZE != 512)
++#error "S3C2410 does not support nand page size != 512"
++#endif
++
++static int is_bad_block(unsigned long i)
++{
++      unsigned char data;
++      unsigned long page_num;
++
++      /* FIXME: do this twice, for first and second page in block */
++
++      nand_clear_RnB();
++#if (NAND_PAGE_SIZE == 512)
++      NFCMD = NAND_CMD_READOOB; /* 0x50 */
++      NFADDR = BAD_BLOCK_OFFSET & 0xf;
++      NFADDR = (i >> 9) & 0xff;
++      NFADDR = (i >> 17) & 0xff;
++      NFADDR = (i >> 25) & 0xff;
++#elif (NAND_PAGE_SIZE == 2048)
++      page_num = i >> 11; /* addr / 2048 */
++      NFCMD = NAND_CMD_READ0;
++      NFADDR = BAD_BLOCK_OFFSET & 0xff;
++      NFADDR = (BAD_BLOCK_OFFSET >> 8) & 0xff;
++      NFADDR = page_num & 0xff;
++      NFADDR = (page_num >> 8) & 0xff;
++      NFADDR = (page_num >> 16) & 0xff;
++      NFCMD = NAND_CMD_READSTART;
++#endif
++      nand_wait();
++      data = (NFDATA & 0xff);
++      if (data != 0xff)
++              return 1;
++
++      return 0;
++}
++
++static int nand_read_page_ll(unsigned char *buf, unsigned long addr)
++{
++      unsigned short *ptr16 = (unsigned short *)buf;
++      unsigned int i, page_num;
++
++      nand_clear_RnB();
++
++      NFCMD = NAND_CMD_READ0;
++
++#if (NAND_PAGE_SIZE == 512)
++      /* Write Address */
++      NFADDR = addr & 0xff;
++      NFADDR = (addr >> 9) & 0xff;
++      NFADDR = (addr >> 17) & 0xff;
++      NFADDR = (addr >> 25) & 0xff;
++#elif (NAND_PAGE_SIZE == 2048)
++      page_num = addr >> 11; /* addr / 2048 */
++      /* Write Address */
++      NFADDR = 0;
++      NFADDR = 0;
++      NFADDR = page_num & 0xff;
++      NFADDR = (page_num >> 8) & 0xff;
++      NFADDR = (page_num >> 16) & 0xff;
++      NFCMD = NAND_CMD_READSTART;
++#else
++#error "unsupported nand page size"
++#endif
++      nand_wait();
++
++#if defined(CONFIG_S3C2410)
++      for (i = 0; i < NAND_PAGE_SIZE; i++) {
++              *buf = (NFDATA & 0xff);
++              buf++;
++      }
++#elif defined(CONFIG_S3C2440)
++      for (i = 0; i < NAND_PAGE_SIZE/2; i++) {
++              *ptr16 = NFDATA16;
++              ptr16++;
++      }
++#endif
++
++      return NAND_PAGE_SIZE;
++}
+ /* low level nand read function */
+ int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
+@@ -50,47 +161,28 @@
+               return -1;      /* invalid alignment */
+       /* chip Enable */
+-      NFCONF &= ~0x800;
++      nand_select();
++      nand_clear_RnB();
+       for (i=0; i<10; i++);
+       for (i=start_addr; i < (start_addr + size);) {
+ #ifdef CONFIG_S3C2410_NAND_SKIP_BAD
+-              if (start_addr % NAND_PAGE_SIZE == 0) {
+-                      unsigned char data;
+-                      NFCMD = 0x50;
+-                      NFADDR = 517&0xf;
+-                      NFADDR = (i >> 9) & 0xff;
+-                      NFADDR = (i >> 17) & 0xff;
+-                      NFADDR = (i >> 25) & 0xff;
+-                      wait_idle();
+-                      data = (NFDATA & 0xff);
+-                      if (data != 0xff) {
++              if (start_addr % NAND_BLOCK_SIZE == 0) {
++                      if (is_bad_block(i)) {
+                               /* Bad block */
+-                              i += NAND_PAGE_SIZE;
+-                              size += NAND_PAGE_SIZE;
++                              i += NAND_BLOCK_SIZE;
++                              size += NAND_BLOCK_SIZE;
+                               continue;
+                       }
+               }
+ #endif
+-              /* READ0 */
+-              NFCMD = 0;
+-
+-              /* Write Address */
+-              NFADDR = i & 0xff;
+-              NFADDR = (i >> 9) & 0xff;
+-              NFADDR = (i >> 17) & 0xff;
+-              NFADDR = (i >> 25) & 0xff;
+-
+-              wait_idle();
+-
+-              for (j=0; j < NAND_SECTOR_SIZE; j++, i++) {
+-                      *buf = (NFDATA & 0xff);
+-                      buf++;
+-              }
++              j = nand_read_page_ll(buf, i);
++              i += j;
++              buf += j;
+       }
+       /* chip Disable */
+-      NFCONF |= 0x800;        /* chip disable */
++      nand_deselect();
+       return 0;
+ }
+Index: u-boot/cpu/arm920t/s3c24x0/nand.c
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/nand.c
++++ u-boot/cpu/arm920t/s3c24x0/nand.c
+@@ -36,24 +36,54 @@
+ #define __REGi(x)     (*(volatile unsigned int *)(x))
+ #define       NF_BASE         0x4e000000
++
+ #define       NFCONF          __REGi(NF_BASE + 0x0)
+-#define       NFCMD           __REGb(NF_BASE + 0x4)
+-#define       NFADDR          __REGb(NF_BASE + 0x8)
+-#define       NFDATA          __REGb(NF_BASE + 0xc)
+-#define       NFSTAT          __REGb(NF_BASE + 0x10)
++
++#if defined(CONFIG_S3C2410)
++
++#define oNFCMD                0x4
++#define       oNFADDR         0x8
++#define oNFDATA               0xc
++#define oNFSTAT               0x10
+ #define NFECC0                __REGb(NF_BASE + 0x14)
+ #define NFECC1                __REGb(NF_BASE + 0x15)
+ #define NFECC2                __REGb(NF_BASE + 0x16)
++#define NFCONF_nFCE   (1<<11)
+ #define S3C2410_NFCONF_EN          (1<<15)
+ #define S3C2410_NFCONF_512BYTE     (1<<14)
+ #define S3C2410_NFCONF_4STEP       (1<<13)
+ #define S3C2410_NFCONF_INITECC     (1<<12)
+-#define S3C2410_NFCONF_nFCE        (1<<11)
+ #define S3C2410_NFCONF_TACLS(x)    ((x)<<8)
+ #define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)
+ #define S3C2410_NFCONF_TWRPH1(x)   ((x)<<0)
++#elif defined(CONFIG_S3C2440)
++
++#define oNFCMD                0x8
++#define oNFADDR               0xc
++#define oNFDATA               0x10
++#define oNFSTAT               0x20
++
++#define       NFCONT          __REGi(NF_BASE + 0x04)
++#define       NFMECC0         __REGi(NF_BASE + 0x2C)
++#define NFCONF_nFCE   (1<<1)
++#define S3C2440_NFCONF_INITECC                (1<<4)
++#define S3C2440_NFCONF_MAINECCLOCK    (1<<5)
++#define nand_select()         (NFCONT &= ~(1 << 1))
++#define nand_deselect()               (NFCONT |= (1 << 1))
++#define nand_clear_RnB()      (NFSTAT |= (1 << 2))
++#define nand_detect_RB()      { while(!(NFSTAT&(1<<2))); }
++#define nand_wait()           { while(!(NFSTAT & 0x4)); } /* RnB_TransDectect */
++
++#endif
++
++#define       NFCMD           __REGb(NF_BASE + oNFCMD)
++#define       NFADDR          __REGb(NF_BASE + oNFADDR)
++#define       NFDATA          __REGb(NF_BASE + oNFDATA)
++#define       NFSTAT          __REGb(NF_BASE + oNFSTAT)
++
++
+ static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd)
+ {
+       struct nand_chip *chip = mtd->priv;
+@@ -62,23 +92,31 @@
+       switch (cmd) {
+       case NAND_CTL_SETNCE:
+-              NFCONF &= ~S3C2410_NFCONF_nFCE;
++#if defined(CONFIG_S3C2410)
++              NFCONF &= ~NFCONF_nFCE;
++#elif defined(CONFIG_S3C2440)
++              NFCONT &= ~NFCONF_nFCE;
++#endif
+               DEBUGN("NFCONF=0x%08x\n", NFCONF);
+               break;
+       case NAND_CTL_CLRNCE:
+-              NFCONF |= S3C2410_NFCONF_nFCE;
++#if defined(CONFIG_S3C2410)
++              NFCONF |= NFCONF_nFCE;
++#elif defined(CONFIG_S3C2440)
++              NFCONT &= ~NFCONF_nFCE;
++#endif
+               DEBUGN("NFCONF=0x%08x\n", NFCONF);
+               break;
+       case NAND_CTL_SETALE:
+-              chip->IO_ADDR_W = NF_BASE + 0x8;
++              chip->IO_ADDR_W = NF_BASE + oNFADDR;
+               DEBUGN("SETALE\n");
+               break;
+       case NAND_CTL_SETCLE:
+-              chip->IO_ADDR_W = NF_BASE + 0x4;
++              chip->IO_ADDR_W = NF_BASE + oNFCMD;
+               DEBUGN("SETCLE\n");
+               break;
+       default:
+-              chip->IO_ADDR_W = NF_BASE + 0xc;
++              chip->IO_ADDR_W = NF_BASE + oNFDATA;
+               break;
+       }
+       return;
+@@ -180,16 +218,21 @@
+       /* initialize hardware */
+       twrph0 = 3; twrph1 = 0; tacls = 0;
++#if defined(CONFIG_S3C2410)
+       cfg = S3C2410_NFCONF_EN;
+       cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
+       cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
+       cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
+       NFCONF = cfg;
+-      //NFCONF = 0xf842;
++#elif defined(CONFIG_S3C2440)
++      twrph0 = 7; twrph1 = 7; tacls = 7;
++      NFCONF = (tacls<<12)|(twrph0<<8)|(twrph1<<4)|(0<<0);
++      NFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
++#endif
+       /* initialize nand_chip data structure */
+-      nand->IO_ADDR_R = nand->IO_ADDR_W = 0x4e00000c;
++      nand->IO_ADDR_R = nand->IO_ADDR_W = NF_BASE + oNFDATA;
+       /* read_buf and write_buf are default */
+       /* read_byte and write_byte are default */
+@@ -214,12 +257,23 @@
+       nand->options = 0;
+ #endif
++#if defined(CONFIG_S3C2440)
++/*
++      nand_select();
++      nand_clear_RnB();
++      NFCMD = NAND_CMD_RESET;
++      { volatile int i; for (i = 0; i < 10; i ++); }
++      nand_detect_RB();
++      nand_deselect();
++*/
++#endif
++
+       DEBUGN("end of nand_init\n");
+       return 0;
+ }
+ #else
+- #error "U-Boot legacy NAND support not available for S3C2410"
++ #error "U-Boot legacy NAND support not available for S3C24xx"
+ #endif
+ #endif
+Index: u-boot/cpu/arm920t/s3c24x0/mmc.c
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/mmc.c
++++ u-boot/cpu/arm920t/s3c24x0/mmc.c
+@@ -137,6 +137,9 @@
+       dcon |= S3C2410_SDIDCON_RXAFTERCMD|S3C2410_SDIDCON_XFER_RXSTART;
+       if (wide)
+               dcon |= S3C2410_SDIDCON_WIDEBUS;
++#if defined(CONFIG_S3C2440)
++      dcon |= S3C2440_SDIDCON_DS_WORD | S3C2440_SDIDCON_DATSTART;
++#endif
+       sdi->SDIDCON = dcon;
+       /* send read command */
+@@ -394,13 +397,18 @@
+       clk_power->CLKCON |= (1 << 9);
++      sdi->SDIBSIZE = 512;
++#if defined(CONFIG_S3C2410)
+       /* S3C2410 has some bug that prevents reliable operation at higher speed */
+       //sdi->SDIPRE = 0x3e;  /* SDCLK = PCLK/2 / (SDIPRE+1) = 396kHz */
+-      sdi->SDIPRE = 0x02;  /* SDCLK = PCLK/2 / (SDIPRE+1) = 396kHz */
+-      sdi->SDIBSIZE = 512;
++      sdi->SDIPRE = 0x02;  /* 2410: SDCLK = PCLK/2 / (SDIPRE+1) = 11MHz */
+       sdi->SDIDTIMER = 0xffff;
++#elif defined(CONFIG_S3C2440)
++      sdi->SDIPRE = 0x05;  /* 2410: SDCLK = PCLK / (SDIPRE+1) = 11MHz */
++      sdi->SDIDTIMER = 0x7fffff;
++#endif
+       sdi->SDIIMSK = 0x0;
+-      sdi->SDICON = S3C2410_SDICON_FIFORESET|S3C2440_SDICON_MMCCLOCK;
++      sdi->SDICON = S3C2410_SDICON_FIFORESET|S3C2410_SDICON_CLOCKTYPE;
+       udelay(125000); /* FIXME: 74 SDCLK cycles */
+       mmc_csd.c_size = 0;
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2443.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-s3c2443.patch
new file mode 100644 (file)
index 0000000..62ae559
--- /dev/null
@@ -0,0 +1,256 @@
+Index: u-boot/cpu/arm920t/start.S
+===================================================================
+--- u-boot.orig/cpu/arm920t/start.S
++++ u-boot/cpu/arm920t/start.S
+@@ -35,6 +35,8 @@
+ #include <s3c2410.h>
+ #elif defined(CONFIG_S3C2440)
+ #include <s3c2440.h>
++#elif defined(CONFIG_S3C2443)
++#include <s3c2443.h>
+ #endif
+@@ -164,9 +166,15 @@
+ # define UPLLCON_val  ((0x3c << 12) + (0x4 << 4) + 0x2)
+ # define CLKDIVN_val  7 /* FCLK:HCLK:PCLK = 1:3:6 */
+ # define CAMDIVN      0x4C000018
++#elif defined(CONFIG_S3C2443)
++# define INTSUBMSK_val        0x1fffffff
++# define EPLLCON_val  ((40 << 16) | (1 << 8) | (1))           /* 96 MHz */
++# define MPLLCON_val  ((81 << 16) | (2 << 8) | (0))           /* 1068 MHz */
++# define CLKDIV0_val  ((8 << 9) | (1 << 4) | (1 << 3) | (1 << 2)
+ #endif
+-#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
++#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || \
++    defined(CONFIG_S3C2440) || defined(CONFIG_S3C2443)
+       ldr     r0, =pWTCON
+       mov     r1, #0x0
+       str     r1, [r0]
+@@ -177,7 +185,7 @@
+       mov     r1, #0xffffffff
+       ldr     r0, =INTMSK
+       str     r1, [r0]
+-# if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
++# if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined(CONFIG_S3C2443)
+       ldr     r1, =INTSUBMSK_val
+       ldr     r0, =INTSUBMSK
+       str     r1, [r0]
+@@ -196,6 +204,43 @@
+       mcr     p15, 0, r1, c1, c0, 0
++#if defined(CONFIG_S3C2443)
++#define LOCKCON0      0x4c000000
++#define LOCKCON1      0x4c000004
++#define MPLLCON               0x4c000010
++#define EPLLCON               0x4c000018
++
++      ldr     r0, =CLKDIV0
++      ldr     r1, =CLKDIV0_val
++      str     r1, [r0]
++
++      /* set safe (way too long) locktime for both PLLs */
++      ldr     r0, =LOCKCON0
++      mov     r1, #0xffffff
++      str     r1, [r0]
++      ldr     r0, =LOCKCON1
++      str     r1, [r0]
++
++      /* configure MPLL */
++      ldr     r0, =MPLLCON
++      ldr     r1, =MPLLCON_val
++      str     r1, [r0]
++
++      /* select MPLL clock out for SYSCLK */
++      ldr     r0, =CLKSRC
++      ldr     r1, [r0]
++      orr     r1, r1, #0x10
++      str     r1, [r0]
++
++#if 0
++      /* configure EPLL */
++      ldr     r0, =EPLLCON
++      ldr     r1, =EPLLCON_val
++      str     r1, [r0]
++#endif
++
++
++#else /* i.e. 2440, 2410 and 2440 */
+ #define LOCKTIME      0x4c000000
+ #define UPLLCON               0x4c000008
+@@ -223,6 +268,7 @@
+       ldr     r0, =CLKDIVN
+       mov     r1, #CLKDIVN_val
+       str     r1, [r0]
++#endif
+ #if 1
+       /* enable uart */
+@@ -249,7 +295,7 @@
+       str     r1, [r0, #0x28]
+ #endif
+-#endif        /* CONFIG_S3C2400 || CONFIG_S3C2410 || CONFIG_S3C2440 */
++#endif        /* CONFIG_S3C2400 || CONFIG_S3C2410 || CONFIG_S3C2440 || CONFIG_S3C2443 */
+ #ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ #ifndef CONFIG_LL_INIT_NAND_ONLY
+Index: u-boot/cpu/arm920t/s3c24x0/interrupts.c
+===================================================================
+--- u-boot.orig/cpu/arm920t/s3c24x0/interrupts.c
++++ u-boot/cpu/arm920t/s3c24x0/interrupts.c
+@@ -31,7 +31,8 @@
+ #include <common.h>
+ #if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || \
+-    defined(CONFIG_S3C2440) || defined (CONFIG_TRAB)
++    defined(CONFIG_S3C2440) || defined(CONFIG_S3C2443) || \
++    defined (CONFIG_TRAB)
+ #include <arm920t.h>
+ #if defined(CONFIG_S3C2400)
+@@ -40,6 +41,8 @@
+ #include <s3c2410.h>
+ #elif defined(CONFIG_S3C2440)
+ #include <s3c2440.h>
++#elif defined(CONFIG_S3C2443)
++#include <s3c2443.h>
+ #endif
+ int timer_load_val = 0;
+@@ -186,6 +189,7 @@
+ #elif defined(CONFIG_SBC2410X) || \
+       defined(CONFIG_SMDK2410) || \
+       defined(CONFIG_SMDK2440) || \
++      defined(CONFIG_SMDK2443) || \
+       defined(CONFIG_VCMA9)
+       tbclk = CFG_HZ;
+ #else
+Index: u-boot/drivers/usbdcore_s3c2410.c
+===================================================================
+--- u-boot.orig/drivers/usbdcore_s3c2410.c
++++ u-boot/drivers/usbdcore_s3c2410.c
+@@ -24,7 +24,8 @@
+ #include <config.h>
+-#if (defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)) && defined(CONFIG_USB_DEVICE)
++#if (defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) || \
++     defined(CONFIG_S3C2443)) && defined(CONFIG_USB_DEVICE)
+ #include <common.h>
+Index: u-boot/include/s3c2443.h
+===================================================================
+--- /dev/null
++++ u-boot/include/s3c2443.h
+@@ -0,0 +1,106 @@
++/*
++ * (C) Copyright 2007 OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * 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
++ */
++
++#ifndef __S3C2443_H
++#define __S3C2443_H
++
++#include <s3c24x0.h>
++
++/* CLOCK & POWER MANAGEMENT (see S3C2443 manual chapter 2) */
++typedef struct {
++      S3C24X0_REG32   LOCKCON0;
++      S3C24X0_REG32   LOCKCON1;
++      S3C24X0_REG32   OSCSET;
++      S3C24X0_REG32   res1;
++      S3C24X0_REG32   MPLLCON;
++      S3C24X0_REG32   res2;
++      S3C24X0_REG32   EPLLCON;
++      S3C24X0_REG32   res3;
++      S3C24X0_REG32   CLKSRC;
++      S3C24X0_REG32   CLKDIV0;
++      S3C24X0_REG32   CLKDIV1;
++      S3C24X0_REG32   res4;
++      S3C24X0_REG32   HCLKCON;
++      S3C24X0_REG32   PCLKCON;
++      S3C24X0_REG32   SCLKCON;
++      S3C24X0_REG32   res5;
++      S3C24X0_REG32   PWRMODE;
++      S3C24X0_REG32   SWRST;
++      S3C24X0_REG32   res6[2];
++      S3C24X0_REG32   BUSPRI0;
++      S3C24X0_REG32   res7[3];
++} /*__attribute__((__packed__))*/ S3C2443_CLOCK_POWER;
++
++/* NAND FLASH (see S3C2443 manual chapter 7) */
++typedef struct {
++      S3C24X0_REG32   NFCONF;
++      S3C24X0_REG32   NFCONT;
++      S3C24X0_REG32   NFCMD;
++      S3C24X0_REG32   NFADDR;
++      S3C24X0_REG32   NFDATA;
++      S3C24X0_REG32   NFMECCD0;
++      S3C24X0_REG32   NFMECCD1;
++      S3C24X0_REG32   NFSECCD;
++      S3C24X0_REG32   NFSBLK;
++      S3C24X0_REG32   NFEBLK;
++      S3C24X0_REG32   NFSTAT;
++      S3C24X0_REG32   NFECCERR0;
++      S3C24X0_REG32   NFECCERR1;
++      S3C24X0_REG32   NFMECC0;
++      S3C24X0_REG32   NFMECC1;
++      S3C24X0_REG32   NFSECC;
++      S3C24X0_REG32   NFMLCBITPT;
++} /*__attribute__((__packed__))*/ S3C2443_NAND;
++
++/* STATIC MEMORY (see S3C2443 manual chapter 5) */
++struct s3c2443_sm_bank {
++      S3C24X0_REG32   SMBIDCYR;
++      S3C24X0_REG32   SMBWSTRDR;
++      S3C24X0_REG32   SMBWSTWRR;
++      S3C24X0_REG32   SMBWSTOENR;
++      S3C24X0_REG32   SMBWSTWENR;
++      S3C24X0_REG32   SMBCR;
++      S3C24X0_REG32   SMBSR;
++      S3C24X0_REG32   SMBWSTBRDR;
++};
++
++typedef struct {
++      struct s3c2443_sm_bank bank[5]; /* 0x4f000000..0x4f0000bf */
++      S3C24X0_REG32   res[0x40];      /* 0x4f0000c0..0x4f0000ff */
++      S3C24X0_REG32   SMBONETYPER;
++      S3C24X0_REG32   SMCSR;
++      S3C24X0_REG32   SMCCR;
++} /*__attribute__((__packed__))*/ S3C2443_SMEM;
++
++
++/* MOBILE DRAM (see S3C2443 manual chapter 6) */
++typedef struct {
++      S3C24X0_REG32   BANKCFG;
++      S3C24X0_REG32   BANKCON1;
++      S3C24X0_REG32   BANKCON2;
++      S3C24X0_REG32   BANKCON3;
++      S3C24X0_REG32   REFRESH;
++      S3C24X0_REG32   TIMEOUT;
++} /*__attribute__((__packed__))*/ S3C2443_MDRAM
++
++#endif /* __S3C2443_H */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-smdk2440.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-smdk2440.patch
new file mode 100644 (file)
index 0000000..09392ad
--- /dev/null
@@ -0,0 +1,1481 @@
+Add support for the Samsung SMDK2440 development board
+
+Index: u-boot/Makefile
+===================================================================
+--- u-boot.orig/Makefile
++++ u-boot/Makefile
+@@ -2035,6 +2035,9 @@
+ smdk2410_config       :       unconfig
+       @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
++smdk2440_config :     unconfig
++      @$(MKCONFIG) $(@:_config=) arm arm920t smdk2440 NULL s3c24x0
++
+ SX1_config :          unconfig
+       @$(MKCONFIG) $(@:_config=) arm arm925t sx1
+Index: u-boot/include/configs/smdk2440.h
+===================================================================
+--- /dev/null
++++ u-boot/include/configs/smdk2440.h
+@@ -0,0 +1,296 @@
++/*
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Marius Groeger <mgroeger@sysgo.de>
++ * Gary Jennejohn <gj@denx.de>
++ * David Mueller <d.mueller@elsoft.ch>
++ *
++ * Configuation settings for the SAMSUNG SMDK2440 board.
++ *
++ * 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
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#if 0
++/* If we want to start u-boot from usb bootloader in NOR flash */
++#define CONFIG_SKIP_RELOCATE_UBOOT    1
++#define       CONFIG_SKIP_LOWLEVEL_INIT       1
++#else
++/* If we want to start u-boot directly from within NAND flash */
++#define CONFIG_LL_INIT_NAND_ONLY
++#define CONFIG_S3C2410_NAND_BOOT      1
++#define CONFIG_S3C2410_NAND_SKIP_BAD  1
++#endif
++
++#define CFG_UBOOT_SIZE                0x40000 /* size of u-boot, for NAND loading */
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++#define CONFIG_ARM920T                1       /* This is an ARM920T Core      */
++#define       CONFIG_S3C2440          1       /* in a SAMSUNG S3C2440 SoC     */
++#define CONFIG_SMDK2440               1       /* on a SAMSUNG SMDK2440 Board  */
++
++/* input clock of PLL */
++#define CONFIG_SYS_CLK_FREQ   16934400/* SMDK2440 has 16.9344MHz input clock */
++
++
++#define USE_920T_MMU          1
++#define CONFIG_USE_IRQ                1
++//#undef CONFIG_USE_IRQ                       /* we don't need IRQ/FIQ stuff */
++
++/*
++ * Size of malloc() pool
++ */
++#define CFG_MALLOC_LEN                (CFG_ENV_SIZE + 2048*1024)
++#define CFG_GBL_DATA_SIZE     128     /* size in bytes reserved for initial data */
++
++/*
++ * Hardware drivers
++ */
++#define CONFIG_DRIVER_CS8900  1       /* we have a CS8900 on-board */
++#define CS8900_BASE           0x19000300
++#define CS8900_BUS16          1 /* the Linux driver does accesses as shorts */
++
++/*
++ * select serial console configuration
++ */
++#define CONFIG_SERIAL1          1     /* we use SERIAL 1 on SMDK2440 */
++#define CONFIG_HWFLOW         1
++
++/************************************************************
++ * RTC
++ ************************************************************/
++#define       CONFIG_RTC_S3C24X0      1
++
++/* allow to overwrite serial and ethaddr */
++#define CONFIG_ENV_OVERWRITE
++
++#define CONFIG_BAUDRATE               115200
++
++/***********************************************************
++ * Command definition
++ ***********************************************************/
++#define CONFIG_COMMANDS \
++                      (CONFIG_CMD_DFL  | \
++                      /*CFG_CMD_BSP    | */ \
++                      CFG_CMD_CACHE    | \
++                      CFG_CMD_DATE     | \
++                      /*CFG_CMD_DHCP   | */ \
++                      CFG_CMD_DIAG     | \
++                      CFG_CMD_ELF      | \
++                      CFG_CMD_EXT2     | \
++                      CFG_CMD_FAT      | \
++                      /*CFG_CMD_HWFLOW         | */ \
++                      /* CFG_CMD_IDE   | */ \
++                      /* CFG_CMD_IRQ   | */ \
++                      CFG_CMD_JFFS2    | \
++                      CFG_CMD_MMC      | \
++                      CFG_CMD_NAND     | \
++                      CFG_CMD_PING     | \
++                      CFG_CMD_PORTIO   | \
++                      CFG_CMD_REGINFO  | \
++                      CFG_CMD_SAVES    | \
++                      CFG_CMD_USB)
++
++/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
++#include <cmd_confdefs.h>
++
++#define CONFIG_BOOTDELAY      3
++#define CONFIG_BOOTARGS       "root=/dev/mtdblock4 rootfstype=jffs2 console=ttySAC2,115200 loglevel=8"
++#define CONFIG_ETHADDR                00:0c:20:02:0a:5b 
++#define CONFIG_NETMASK          255.255.255.0
++#define CONFIG_IPADDR         192.168.1.100
++#define CONFIG_SERVERIP               192.168.1.21
++/*#define CONFIG_BOOTFILE     "elinos-lart" */
++//#define CONFIG_BOOTCOMMAND  "nand read 0x32000000 0x34000 0x200000; bootm"
++#define CONFIG_BOOTCOMMAND    "nand read.e 0x32000000 0x100000 0x200000; bootm"
++
++#define CONFIG_DOS_PARTITION  1
++                      
++#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
++#define CONFIG_KGDB_BAUDRATE  115200          /* speed to run kgdb serial port */
++/* what's this ? it's not used anywhere */
++#define CONFIG_KGDB_SER_INDEX 1               /* which serial port to use */
++#endif
++
++/*
++ * Miscellaneous configurable options
++ */
++#define       CFG_LONGHELP                            /* undef to save memory         */
++#define       CFG_PROMPT              "SMDK2440 # "   /* Monitor Command Prompt       */
++#define       CFG_CBSIZE              256             /* Console I/O Buffer Size      */
++#define       CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
++#define       CFG_MAXARGS             32              /* max number of command args   */
++#define CFG_BARGSIZE          CFG_CBSIZE      /* Boot Argument Buffer Size    */
++
++#define CFG_MEMTEST_START     0x30000000      /* memtest works on     */
++#define CFG_MEMTEST_END               0x33F00000      /* 63 MB in DRAM        */
++
++#undef  CFG_CLKS_IN_HZ                /* everything, incl board info, in Hz */
++
++#define       CFG_LOAD_ADDR           0x32000000      /* default load address */
++
++/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
++/* it to wrap 100 times (total 1562500) to get 1 sec. */
++#define       CFG_HZ                  1562500
++
++/* valid baudrates */
++#define CFG_BAUDRATE_TABLE    { 9600, 19200, 38400, 57600, 115200 }
++
++/*-----------------------------------------------------------------------
++ * Stack sizes
++ *
++ * The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE      (512*1024)      /* regular stack */
++#ifdef CONFIG_USE_IRQ
++#define CONFIG_STACKSIZE_IRQ  (8*1024)        /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ  (4*1024)        /* FIQ stack */
++#endif
++
++/* IDE/ATA config */
++
++#if 0
++#define CFG_IDE_MAXBUS                1
++#define CFG_IDE_MAXDEVICE     2
++#define CFG_IDE_PREINIT               0
++
++#define CFG_ATA_BASE_ADDR     
++#endif
++
++#define CONFIG_USB_OHCI               1
++
++#define CONFIG_USB_DEVICE     1
++#define CONFIG_USB_TTY                1
++#define CFG_CONSOLE_IS_IN_ENV 1
++#define CONFIG_USBD_VENDORID          0x1457  /* FIC */
++#define CONFIG_USBD_PRODUCTID_GSERIAL 0x5120  /* gserial */
++#define CONFIG_USBD_PRODUCTID_CDCACM  0x511b  /* SMDK2440 CDC ACM */
++#define CONFIG_USBD_MANUFACTURER      "OpenMoko, Inc."
++#define CONFIG_USBD_PRODUCT_NAME      "S3C2440 Bootloader " U_BOOT_VERSION
++#define CONFIG_EXTRA_ENV_SETTINGS     "usbtty=cdc_acm\0"
++#define CONFIG_USBD_DFU                       1
++#define CONFIG_USBD_DFU_XFER_SIZE     4096
++#define CONFIG_USBD_DFU_INTERFACE     2
++
++/*-----------------------------------------------------------------------
++ * Physical Memory Map
++ */
++#define CONFIG_NR_DRAM_BANKS  1          /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1          0x30000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE     0x04000000 /* 64 MB */
++
++#define PHYS_FLASH_1          0x00000000 /* Flash Bank #1 */
++
++#define CFG_FLASH_BASE                PHYS_FLASH_1
++
++/*-----------------------------------------------------------------------
++ * FLASH and environment organization
++ */
++
++#define CONFIG_AMD_LV400      1       /* uncomment this if you have a LV400 flash */
++#if 0
++#define CONFIG_AMD_LV800      1       /* uncomment this if you have a LV800 flash */
++#endif
++
++#define CFG_MAX_FLASH_BANKS   1       /* max number of memory banks */
++#ifdef CONFIG_AMD_LV800
++#define PHYS_FLASH_SIZE               0x00100000 /* 1MB */
++#define CFG_MAX_FLASH_SECT    (19)    /* max number of sectors on one chip */
++#define CFG_ENV_ADDR          (CFG_FLASH_BASE + 0x0F0000) /* addr of environment */
++#endif
++#ifdef CONFIG_AMD_LV400
++#define PHYS_FLASH_SIZE               0x00080000 /* 512KB */
++#define CFG_MAX_FLASH_SECT    (11)    /* max number of sectors on one chip */
++#define CFG_ENV_ADDR          (CFG_FLASH_BASE + 0x070000) /* addr of environment */
++#endif
++
++/* timeout values are in ticks */
++#define CFG_FLASH_ERASE_TOUT  (5*CFG_HZ) /* Timeout for Flash Erase */
++#define CFG_FLASH_WRITE_TOUT  (5*CFG_HZ) /* Timeout for Flash Write */
++
++#define       CFG_ENV_IS_IN_NAND      1
++#define CFG_ENV_SIZE          0x20000         /* 128k Total Size of Environment Sector */
++#define CFG_ENV_OFFSET_OOB    1
++#define CFG_PREBOOT_OVERRIDE  1
++
++#define NAND_MAX_CHIPS                1
++#define CFG_NAND_BASE         0x4e000000
++#define CFG_MAX_NAND_DEVICE   1
++
++#define CONFIG_MMC            1
++#define CFG_MMC_BASE          0xff000000
++
++#define CONFIG_EXT2           1
++
++#define CONFIG_NEW_QT2440     0
++
++/* FAT driver in u-boot is broken currently */
++#define CONFIG_FAT            1
++#define CONFIG_SUPPORT_VFAT
++
++#if 1
++/* JFFS2 driver */
++#define CONFIG_JFFS2_CMDLINE  1
++#define CONFIG_JFFS2_NAND     1
++#define CONFIG_JFFS2_NAND_DEV 0
++//#define CONFIG_JFFS2_NAND_OFF               0x634000
++//#define CONFIG_JFFS2_NAND_SIZE      0x39cc000
++#endif
++
++/* ATAG configuration */
++#define CONFIG_INITRD_TAG             1
++#define CONFIG_SETUP_MEMORY_TAGS      1
++#define CONFIG_CMDLINE_TAG            1
++#if 0
++#define CONFIG_SERIAL_TAG             1
++#define CONFIG_REVISION_TAG           1
++#endif
++
++
++#if 0
++#define CONFIG_VIDEO
++#define CONFIG_VIDEO_S3C2410
++#define CONFIG_CFB_CONSOLE
++#define CONFIG_VIDEO_LOGO
++#define CONFIG_VGA_AS_SINGLE_DEVICE
++
++#define VIDEO_KBD_INIT_FCT    0
++#define VIDEO_TSTC_FCT                serial_tstc
++#define VIDEO_GETC_FCT                serial_getc
++
++#define LCD_VIDEO_ADDR                0x33d00000
++#endif
++
++#define CONFIG_S3C2410_NAND_BBT               1
++//#define CONFIG_S3C2410_NAND_HWECC   1
++
++#define CFG_NAND_YAFFS_WRITE
++#define CFG_NAND_YAFFS1_NEW_OOB_LAYOUT
++
++#define MTDIDS_DEFAULT                "nand0=smdk2440-nand"
++#define MTPARTS_DEFAULT               "smdk2440-nand:0x00100000(u-boot),0x00200000(kernel),0x00200000(update),0x00100000(splash),0x01400000(jffs2),-(temp)"
++#define CFG_NAND_DYNPART_MTD_KERNEL_NAME "smdk2440-nand"
++#define CONFIG_NAND_DYNPART
++
++#endif        /* __CONFIG_H */
+Index: u-boot/include/configs/smdk2440nand.h
+===================================================================
+--- /dev/null
++++ u-boot/include/configs/smdk2440nand.h
+@@ -0,0 +1,47 @@
++/*
++ * (C) Copyright 2004 
++ *  Samsung Electronics  : SW.LEE <hitchcar@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.
++ *
++ */
++
++#ifndef __SMDK2440_NAND_H
++#define __SMDK2440_NAND_H
++
++#define CFG_ENV_NAND_BLOCK     8
++
++#if 0 //old flash
++#define NAND_OOB_SIZE           (16)
++#define NAND_PAGES_IN_BLOCK     (32)
++#define NAND_PAGE_SIZE          (512)
++
++#define NAND_BLOCK_SIZE         (NAND_PAGE_SIZE*NAND_PAGES_IN_BLOCK)
++#define NAND_BLOCK_MASK         (NAND_BLOCK_SIZE - 1)
++#define NAND_PAGE_MASK          (NAND_PAGE_SIZE - 1)
++#else //new flash
++#define NAND_OOB_SIZE           (64)
++#define NAND_PAGES_IN_BLOCK     (64)
++#define NAND_PAGE_SIZE          (2048)
++
++#define NAND_BLOCK_SIZE         (NAND_PAGE_SIZE*NAND_PAGES_IN_BLOCK)
++#define NAND_BLOCK_MASK         (NAND_BLOCK_SIZE - 1)
++#define NAND_PAGE_MASK          (NAND_PAGE_SIZE - 1)
++
++#endif
++
++
++
++//#define NAND_3_ADDR_CYCLE   1
++//#define S3C24X0_16BIT_NAND  1
++
++#ifdef KINGFISH
++#undef S3C24X0_16BIT_NAND     
++#define S3C24X0_16BIT_NAND    1
++#endif
++
++#endif        
++
+Index: u-boot/board/smdk2440/Makefile
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2440/Makefile
+@@ -0,0 +1,67 @@
++#
++# (C) Copyright 2000-2006
++# Wolfgang Denk, DENX Software Engineering, wd@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
++#
++
++include $(TOPDIR)/config.mk
++
++LIB   = $(obj)lib$(BOARD).a
++
++COBJS := smdk2440.o flash.o udc.o
++SOBJS := lowlevel_init.o
++
++.PHONY:       all
++
++all:  $(LIB) lowlevel_foo.bin
++
++SRCS  := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS  := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB):       $(obj).depend $(OBJS) $(SOBJS)
++      $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
++
++lowlevel_foo.o:       lowlevel_foo.S
++      $(CC) -c -DTEXT_BASE=0x33F80000 -march=armv4 \
++        -o lowlevel_foo.o lowlevel_foo.S
++
++lowlevel_foo: lowlevel_foo.o lowlevel_init.o lowlevel_foo.lds
++      $(LD) -T ./lowlevel_foo.lds -Ttext 0x33f80000 -Bstatic \
++        lowlevel_init.o lowlevel_foo.o -o lowlevel_foo
++
++lowlevel_foo.bin:     lowlevel_foo
++      $(CROSS_COMPILE)objcopy --gap-fill=0xff -O binary \
++        lowlevel_foo lowlevel_foo.bin
++
++clean:
++      rm -f $(SOBJS) $(OBJS)
++
++distclean:    clean
++      rm -f $(LIB) core *.bak .depend
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+Index: u-boot/board/smdk2440/config.mk
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2440/config.mk
+@@ -0,0 +1,29 @@
++#
++# (C) Copyright 2002
++# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
++# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++#
++# SAMSUNG SMDK2440 board with S3C2440 (ARM920T) cpu
++#
++# see http://www.samsung.com/ for more information on SAMSUNG
++#
++
++CONFIG_USB_DFU_VENDOR=0x1457
++CONFIG_USB_DFU_PRODUCT=0x511b
++CONFIG_USB_DFU_REVISION=0x0100
++
++#
++# SMDK2440 has 1 bank of 64 MB DRAM
++#
++# 3000'0000 to 3400'0000
++#
++# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
++# optionally with a ramdisk at 3080'0000
++#
++# we load ourself to 33F8'0000
++#
++# download area is 3300'0000
++#
++
++
++TEXT_BASE = 0x33F80000
+Index: u-boot/board/smdk2440/flash.c
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2440/flash.c
+@@ -0,0 +1,433 @@
++/*
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Alex Zuepke <azu@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>
++
++ulong myflush (void);
++
++
++#define FLASH_BANK_SIZE       PHYS_FLASH_SIZE
++#define MAIN_SECT_SIZE  0x10000       /* 64 KB */
++
++flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
++
++
++#define CMD_READ_ARRAY                0x000000F0
++#define CMD_UNLOCK1           0x000000AA
++#define CMD_UNLOCK2           0x00000055
++#define CMD_ERASE_SETUP               0x00000080
++#define CMD_ERASE_CONFIRM     0x00000030
++#define CMD_PROGRAM           0x000000A0
++#define CMD_UNLOCK_BYPASS     0x00000020
++
++#define MEM_FLASH_ADDR1               (*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555 << 1)))
++#define MEM_FLASH_ADDR2               (*(volatile u16 *)(CFG_FLASH_BASE + (0x000002AA << 1)))
++
++#define BIT_ERASE_DONE                0x00000080
++#define BIT_RDY_MASK          0x00000080
++#define BIT_PROGRAM_ERROR     0x00000020
++#define BIT_TIMEOUT           0x80000000      /* our flag */
++
++#define READY 1
++#define ERR   2
++#define TMO   4
++
++/*-----------------------------------------------------------------------
++ */
++
++ulong flash_init (void)
++{
++      int i, j;
++      ulong size = 0;
++
++      for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
++              ulong flashbase = 0;
++
++              flash_info[i].flash_id =
++#if defined(CONFIG_AMD_LV400)
++                      (AMD_MANUFACT & FLASH_VENDMASK) |
++                      (AMD_ID_LV400B & FLASH_TYPEMASK);
++#elif defined(CONFIG_AMD_LV800)
++                      (AMD_MANUFACT & FLASH_VENDMASK) |
++                      (AMD_ID_LV800B & FLASH_TYPEMASK);
++#else
++#error "Unknown flash configured"
++#endif
++                      flash_info[i].size = FLASH_BANK_SIZE;
++              flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
++              memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
++              if (i == 0)
++                      flashbase = PHYS_FLASH_1;
++              else
++                      panic ("configured too many flash banks!\n");
++              for (j = 0; j < flash_info[i].sector_count; j++) {
++                      if (j <= 3) {
++                              /* 1st one is 16 KB */
++                              if (j == 0) {
++                                      flash_info[i].start[j] =
++                                              flashbase + 0;
++                              }
++
++                              /* 2nd and 3rd are both 8 KB */
++                              if ((j == 1) || (j == 2)) {
++                                      flash_info[i].start[j] =
++                                              flashbase + 0x4000 + (j -
++                                                                    1) *
++                                              0x2000;
++                              }
++
++                              /* 4th 32 KB */
++                              if (j == 3) {
++                                      flash_info[i].start[j] =
++                                              flashbase + 0x8000;
++                              }
++                      } else {
++                              flash_info[i].start[j] =
++                                      flashbase + (j - 3) * MAIN_SECT_SIZE;
++                      }
++              }
++              size += flash_info[i].size;
++      }
++
++      flash_protect (FLAG_PROTECT_SET,
++                     CFG_FLASH_BASE,
++                     CFG_FLASH_BASE + monitor_flash_len - 1,
++                     &flash_info[0]);
++
++      flash_protect (FLAG_PROTECT_SET,
++                     CFG_ENV_ADDR,
++                     CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
++
++      return size;
++}
++
++/*-----------------------------------------------------------------------
++ */
++void flash_print_info (flash_info_t * info)
++{
++      int i;
++
++      switch (info->flash_id & FLASH_VENDMASK) {
++      case (AMD_MANUFACT & FLASH_VENDMASK):
++              printf ("AMD: ");
++              break;
++      default:
++              printf ("Unknown Vendor ");
++              break;
++      }
++
++      switch (info->flash_id & FLASH_TYPEMASK) {
++      case (AMD_ID_LV400B & FLASH_TYPEMASK):
++              printf ("1x Amd29LV400BB (4Mbit)\n");
++              break;
++      case (AMD_ID_LV800B & FLASH_TYPEMASK):
++              printf ("1x Amd29LV800BB (8Mbit)\n");
++              break;
++      default:
++              printf ("Unknown Chip Type\n");
++              goto Done;
++              break;
++      }
++
++      printf ("  Size: %ld MB in %d Sectors\n",
++              info->size >> 20, info->sector_count);
++
++      printf ("  Sector Start Addresses:");
++      for (i = 0; i < info->sector_count; i++) {
++              if ((i % 5) == 0) {
++                      printf ("\n   ");
++              }
++              printf (" %08lX%s", info->start[i],
++                      info->protect[i] ? " (RO)" : "     ");
++      }
++      printf ("\n");
++
++      Done:;
++}
++
++/*-----------------------------------------------------------------------
++ */
++
++int flash_erase (flash_info_t * info, int s_first, int s_last)
++{
++      ushort result;
++      int iflag, cflag, prot, sect;
++      int rc = ERR_OK;
++      int chip;
++
++      /* first look for protection bits */
++
++      if (info->flash_id == FLASH_UNKNOWN)
++              return ERR_UNKNOWN_FLASH_TYPE;
++
++      if ((s_first < 0) || (s_first > s_last)) {
++              return ERR_INVAL;
++      }
++
++      if ((info->flash_id & FLASH_VENDMASK) !=
++          (AMD_MANUFACT & FLASH_VENDMASK)) {
++              return ERR_UNKNOWN_FLASH_VENDOR;
++      }
++
++      prot = 0;
++      for (sect = s_first; sect <= s_last; ++sect) {
++              if (info->protect[sect]) {
++                      prot++;
++              }
++      }
++      if (prot)
++              return ERR_PROTECTED;
++
++      /*
++       * Disable interrupts which might cause a timeout
++       * here. Remember that our exception vectors are
++       * at address 0 in the flash, and we don't want a
++       * (ticker) exception to happen while the flash
++       * chip is in programming mode.
++       */
++      cflag = icache_status ();
++      icache_disable ();
++      iflag = disable_interrupts ();
++
++      /* Start erase on unprotected sectors */
++      for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
++              printf ("Erasing sector %2d ... ", sect);
++
++              /* arm simple, non interrupt dependent timer */
++              reset_timer_masked ();
++
++              if (info->protect[sect] == 0) { /* not protected */
++                      vu_short *addr = (vu_short *) (info->start[sect]);
++
++                      MEM_FLASH_ADDR1 = CMD_UNLOCK1;
++                      MEM_FLASH_ADDR2 = CMD_UNLOCK2;
++                      MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
++
++                      MEM_FLASH_ADDR1 = CMD_UNLOCK1;
++                      MEM_FLASH_ADDR2 = CMD_UNLOCK2;
++                      *addr = CMD_ERASE_CONFIRM;
++
++                      /* wait until flash is ready */
++                      chip = 0;
++
++                      do {
++                              result = *addr;
++
++                              /* check timeout */
++                              if (get_timer_masked () >
++                                  CFG_FLASH_ERASE_TOUT) {
++                                      MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
++                                      chip = TMO;
++                                      break;
++                              }
++
++                              if (!chip
++                                  && (result & 0xFFFF) & BIT_ERASE_DONE)
++                                      chip = READY;
++
++                              if (!chip
++                                  && (result & 0xFFFF) & BIT_PROGRAM_ERROR)
++                                      chip = ERR;
++
++                      } while (!chip);
++
++                      MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
++
++                      if (chip == ERR) {
++                              rc = ERR_PROG_ERROR;
++                              goto outahere;
++                      }
++                      if (chip == TMO) {
++                              rc = ERR_TIMOUT;
++                              goto outahere;
++                      }
++
++                      printf ("ok.\n");
++              } else {        /* it was protected */
++
++                      printf ("protected!\n");
++              }
++      }
++
++      if (ctrlc ())
++              printf ("User Interrupt!\n");
++
++      outahere:
++      /* allow flash to settle - wait 10 ms */
++      udelay_masked (10000);
++
++      if (iflag)
++              enable_interrupts ();
++
++      if (cflag)
++              icache_enable ();
++
++      return rc;
++}
++
++/*-----------------------------------------------------------------------
++ * Copy memory to flash
++ */
++
++volatile static int write_hword (flash_info_t * info, ulong dest, ushort data)
++{
++      vu_short *addr = (vu_short *) dest;
++      ushort result;
++      int rc = ERR_OK;
++      int cflag, iflag;
++      int chip;
++
++      /*
++       * Check if Flash is (sufficiently) erased
++       */
++      result = *addr;
++      if ((result & data) != data)
++              return ERR_NOT_ERASED;
++
++
++      /*
++       * Disable interrupts which might cause a timeout
++       * here. Remember that our exception vectors are
++       * at address 0 in the flash, and we don't want a
++       * (ticker) exception to happen while the flash
++       * chip is in programming mode.
++       */
++      cflag = icache_status ();
++      icache_disable ();
++      iflag = disable_interrupts ();
++
++      MEM_FLASH_ADDR1 = CMD_UNLOCK1;
++      MEM_FLASH_ADDR2 = CMD_UNLOCK2;
++      MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
++      *addr = CMD_PROGRAM;
++      *addr = data;
++
++      /* arm simple, non interrupt dependent timer */
++      reset_timer_masked ();
++
++      /* wait until flash is ready */
++      chip = 0;
++      do {
++              result = *addr;
++
++              /* check timeout */
++              if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
++                      chip = ERR | TMO;
++                      break;
++              }
++              if (!chip && ((result & 0x80) == (data & 0x80)))
++                      chip = READY;
++
++              if (!chip && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) {
++                      result = *addr;
++
++                      if ((result & 0x80) == (data & 0x80))
++                              chip = READY;
++                      else
++                              chip = ERR;
++              }
++
++      } while (!chip);
++
++      *addr = CMD_READ_ARRAY;
++
++      if (chip == ERR || *addr != data)
++              rc = ERR_PROG_ERROR;
++
++      if (iflag)
++              enable_interrupts ();
++
++      if (cflag)
++              icache_enable ();
++
++      return rc;
++}
++
++/*-----------------------------------------------------------------------
++ * Copy memory to flash.
++ */
++
++int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
++{
++      ulong cp, wp;
++      int l;
++      int i, rc;
++      ushort data;
++
++      wp = (addr & ~1);       /* get lower word aligned address */
++
++      /*
++       * handle unaligned start bytes
++       */
++      if ((l = addr - wp) != 0) {
++              data = 0;
++              for (i = 0, cp = wp; i < l; ++i, ++cp) {
++                      data = (data >> 8) | (*(uchar *) cp << 8);
++              }
++              for (; i < 2 && cnt > 0; ++i) {
++                      data = (data >> 8) | (*src++ << 8);
++                      --cnt;
++                      ++cp;
++              }
++              for (; cnt == 0 && i < 2; ++i, ++cp) {
++                      data = (data >> 8) | (*(uchar *) cp << 8);
++              }
++
++              if ((rc = write_hword (info, wp, data)) != 0) {
++                      return (rc);
++              }
++              wp += 2;
++      }
++
++      /*
++       * handle word aligned part
++       */
++      while (cnt >= 2) {
++              data = *((vu_short *) src);
++              if ((rc = write_hword (info, wp, data)) != 0) {
++                      return (rc);
++              }
++              src += 2;
++              wp += 2;
++              cnt -= 2;
++      }
++
++      if (cnt == 0) {
++              return ERR_OK;
++      }
++
++      /*
++       * handle unaligned tail bytes
++       */
++      data = 0;
++      for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
++              data = (data >> 8) | (*src++ << 8);
++              --cnt;
++      }
++      for (; i < 2; ++i, ++cp) {
++              data = (data >> 8) | (*(uchar *) cp << 8);
++      }
++
++      return write_hword (info, wp, data);
++}
+Index: u-boot/board/smdk2440/lowlevel_init.S
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2440/lowlevel_init.S
+@@ -0,0 +1,167 @@
++/*
++ * Memory Setup stuff - taken from blob memsetup.S
++ *
++ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
++ *                     Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
++ *
++ * Modified for the Samsung SMDK2410 by
++ * (C) Copyright 2002
++ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++ *
++ * 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 <version.h>
++
++
++/* some parameters for the board */
++
++/*
++ *
++ * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
++ *
++ * Copyright (C) 2002 Samsung Electronics SW.LEE  <hitchcar@sec.samsung.com>
++ *
++ */
++
++#define BWSCON        0x48000000
++
++/* BWSCON */
++#define DW8                   (0x0)
++#define DW16                  (0x1)
++#define DW32                  (0x2)
++#define WAIT                  (0x1<<2)
++#define UBLB                  (0x1<<3)
++
++#define B1_BWSCON             (DW32)
++#define B2_BWSCON             (DW16)
++#define B3_BWSCON             (DW16 + WAIT + UBLB)
++#define B4_BWSCON             (DW16)
++#define B5_BWSCON             (DW16)
++#define B6_BWSCON             (DW32)
++#define B7_BWSCON             (DW32)
++
++/* BANK0CON */
++#define B0_Tacs                       0x0     /*  0clk */
++#define B0_Tcos                       0x0     /*  0clk */
++#define B0_Tacc                       0x7     /* 14clk */
++#define B0_Tcoh                       0x0     /*  0clk */
++#define B0_Tah                        0x0     /*  0clk */
++#define B0_Tacp                       0x0
++#define B0_PMC                        0x0     /* normal */
++
++/* BANK1CON */
++#define B1_Tacs                       0x0     /*  0clk */
++#define B1_Tcos                       0x0     /*  0clk */
++#define B1_Tacc                       0x7     /* 14clk */
++#define B1_Tcoh                       0x0     /*  0clk */
++#define B1_Tah                        0x0     /*  0clk */
++#define B1_Tacp                       0x0
++#define B1_PMC                        0x0
++
++#define B2_Tacs                       0x0
++#define B2_Tcos                       0x0
++#define B2_Tacc                       0x7
++#define B2_Tcoh                       0x0
++#define B2_Tah                        0x0
++#define B2_Tacp                       0x0
++#define B2_PMC                        0x0
++
++#define B3_Tacs                       0x0     /*  0clk */
++#define B3_Tcos                       0x3     /*  4clk */
++#define B3_Tacc                       0x7     /* 14clk */
++#define B3_Tcoh                       0x1     /*  1clk */
++#define B3_Tah                        0x0     /*  0clk */
++#define B3_Tacp                       0x3     /*  6clk */
++#define B3_PMC                        0x0     /* normal */
++
++#define B4_Tacs                       0x0     /*  0clk */
++#define B4_Tcos                       0x0     /*  0clk */
++#define B4_Tacc                       0x7     /* 14clk */
++#define B4_Tcoh                       0x0     /*  0clk */
++#define B4_Tah                        0x0     /*  0clk */
++#define B4_Tacp                       0x0
++#define B4_PMC                        0x0     /* normal */
++
++#define B5_Tacs                       0x0     /*  0clk */
++#define B5_Tcos                       0x0     /*  0clk */
++#define B5_Tacc                       0x7     /* 14clk */
++#define B5_Tcoh                       0x0     /*  0clk */
++#define B5_Tah                        0x0     /*  0clk */
++#define B5_Tacp                       0x0
++#define B5_PMC                        0x0     /* normal */
++
++#define B6_MT                 0x3     /* SDRAM */
++#define B6_Trcd                       0x1
++#define B6_SCAN                       0x1     /* 9bit */
++
++#define B7_MT                 0x3     /* SDRAM */
++#define B7_Trcd                       0x1     /* 3clk */
++#define B7_SCAN                       0x1     /* 9bit */
++
++/* REFRESH parameter */
++#define REFEN                 0x1     /* Refresh enable */
++#define TREFMD                        0x0     /* CBR(CAS before RAS)/Auto refresh */
++#define Trp                   0x0     /* 2clk */
++#define Trc                   0x3     /* 7clk */
++#define Tchr                  0x2     /* 3clk */
++#define REFCNT                        1113    /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
++/**************************************/
++
++_TEXT_BASE:
++      .word   TEXT_BASE
++
++.globl lowlevel_init
++lowlevel_init:
++      /* memory control configuration */
++      /* make r0 relative the current location so that it */
++      /* reads SMRDATA out of FLASH rather than memory ! */
++      ldr     r0, =SMRDATA
++      ldr     r1, _TEXT_BASE
++      sub     r0, r0, r1
++      ldr     r1, =BWSCON     /* Bus Width Status Controller */
++      add     r2, r0, #13*4
++0:
++      ldr     r3, [r0], #4
++      str     r3, [r1], #4
++      cmp     r2, r0
++      bne     0b
++
++      /* everything is fine now */
++      mov     pc, lr
++
++      .ltorg
++/* the literal pools origin */
++
++SMRDATA:
++    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
++    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
++    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
++    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
++    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
++    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
++    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
++    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
++    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
++    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
++    .word 0x32
++    .word 0x30
++    .word 0x30
+Index: u-boot/board/smdk2440/smdk2440.c
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2440/smdk2440.c
+@@ -0,0 +1,152 @@
++/*
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Marius Groeger <mgroeger@sysgo.de>
++ *
++ * (C) Copyright 2002
++ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++ *
++ * 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 <s3c2440.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#define FCLK_SPEED 1
++
++#if FCLK_SPEED==0             /* Fout = 203MHz, Fin = 12MHz for Audio */
++#define M_MDIV        0xC3
++#define M_PDIV        0x4
++#define M_SDIV        0x1
++#elif FCLK_SPEED==1           /* Fout = 399.65MHz */
++#define M_MDIV        0x6e
++#define M_PDIV        0x3
++#define M_SDIV        0x1
++#endif
++
++#define USB_CLOCK 1
++
++#if USB_CLOCK==0
++#define U_M_MDIV      0xA1
++#define U_M_PDIV      0x3
++#define U_M_SDIV      0x1
++#elif USB_CLOCK==1
++#define U_M_MDIV      0x3c
++#define U_M_PDIV      0x4
++#define U_M_SDIV      0x2
++#endif
++
++static inline void delay (unsigned long loops)
++{
++      __asm__ volatile ("1:\n"
++        "subs %0, %1, #1\n"
++        "bne 1b":"=r" (loops):"0" (loops));
++}
++
++/*
++ * Miscellaneous platform dependent initialisations
++ */
++
++int board_init (void)
++{
++      S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++      /* to reduce PLL lock time, adjust the LOCKTIME register */
++      clk_power->LOCKTIME = 0xFFFFFF;
++
++      /* configure MPLL */
++      clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
++
++      /* some delay between MPLL and UPLL */
++      delay (4000);
++
++      /* configure UPLL */
++      clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
++
++      /* some delay between MPLL and UPLL */
++      delay (8000);
++
++      /* set up the I/O ports */
++      gpio->GPACON = 0x007FFFFF;
++      gpio->GPBCON = 0x002a9655;
++      gpio->GPBUP = 0x000007FF;
++      gpio->GPCCON = 0xAAAAAAAA;
++      gpio->GPCUP = 0x0000FFFF;
++      gpio->GPDCON = 0xAAAAAAAA;
++      gpio->GPDUP = 0x0000FFFF;
++      gpio->GPECON = 0xAAAAAAAA;
++      gpio->GPEUP = 0x0000FFFF;
++      gpio->GPFCON = 0x000055AA;
++      gpio->GPFUP = 0x000000FF;
++      gpio->GPGCON = 0xFD95FFBA;
++      gpio->GPGUP = 0x0000FFFF;
++#ifdef CONFIG_SERIAL3
++      gpio->GPHCON = 0x002AAAAA;
++#else
++      gpio->GPHCON = 0x002AFAAA;
++#endif
++      gpio->GPHUP = 0x000007FF;
++
++      gpio->GPJCON = 0x2AAAAAA;
++
++#if 0
++      /* USB Device Part */
++      /*GPGCON is reset for USB Device */
++      gpio->GPGCON = (gpio->GPGCON & ~(3 << 24)) | (1 << 24); /* Output Mode */
++      gpio->GPGUP = gpio->GPGUP | ( 1 << 12);                 /* Pull up disable */
++
++      gpio->GPGDAT |= ( 1 << 12) ; 
++      gpio->GPGDAT &= ~( 1 << 12) ; 
++      udelay(20000);
++      gpio->GPGDAT |= ( 1 << 12) ; 
++#endif
++
++      /* arch number of SMDK2440-Board */
++      gd->bd->bi_arch_number = MACH_TYPE_S3C2440;
++
++      /* adress of boot parameters */
++      gd->bd->bi_boot_params = 0x30000100;
++
++      icache_enable();
++      dcache_enable();
++
++      return 0;
++}
++
++int dram_init (void)
++{
++      gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
++      gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
++
++      return 0;
++}
++
++/* The sum of all part_size[]s must equal to the NAND size, i.e., 0x4000000.
++   "initrd" is sized such that it can hold two uncompressed 16 bit 640*480
++   images: 640*480*2*2 = 1228800 < 1245184. */
++
++unsigned int dynpart_size[] = {
++    CFG_UBOOT_SIZE, 0x20000, 0x200000, 0xa0000, 0x3d5c000-CFG_UBOOT_SIZE, 0 };
++char *dynpart_names[] = {
++    "u-boot", "u-boot_env", "kernel", "splash", "rootfs", NULL };
++
++
+Index: u-boot/board/smdk2440/u-boot.lds
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2440/u-boot.lds
+@@ -0,0 +1,58 @@
++/*
++ * (C) Copyright 2002
++ * Gary Jennejohn, DENX Software Engineering, <gj@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_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
++OUTPUT_ARCH(arm)
++ENTRY(_start)
++SECTIONS
++{
++      . = 0x00000000;
++
++      . = ALIGN(4);
++      .text      :
++      {
++        cpu/arm920t/start.o   (.text)
++        cpu/arm920t/s3c24x0/nand_read.o (.text)
++        *(.text)
++      }
++
++      . = ALIGN(4);
++      .rodata : { *(.rodata) }
++
++      . = ALIGN(4);
++      .data : { *(.data) }
++
++      . = ALIGN(4);
++      .got : { *(.got) }
++
++      . = .;
++      __u_boot_cmd_start = .;
++      .u_boot_cmd : { *(.u_boot_cmd) }
++      __u_boot_cmd_end = .;
++
++      . = ALIGN(4);
++      __bss_start = .;
++      .bss : { *(.bss) }
++      _end = .;
++}
+Index: u-boot/board/smdk2440/udc.c
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2440/udc.c
+@@ -0,0 +1,23 @@
++
++#include <common.h>
++#include <usbdcore.h>
++#include <s3c2440.h>
++
++void udc_ctrl(enum usbd_event event, int param)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++      switch (event) {
++      case UDC_CTRL_PULLUP_ENABLE:
++              if (param)
++                      gpio->GPGDAT |= (1 << 12);
++              else
++                      gpio->GPGDAT &= ~(1 << 12);
++              break;
++      case UDC_CTRL_500mA_ENABLE:
++              /* IGNORE */
++              break;
++      default:
++              break;
++      }
++}
+Index: u-boot/board/smdk2440/lowlevel_foo.S
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2440/lowlevel_foo.S
+@@ -0,0 +1,82 @@
++
++_start:
++      b       reset
++undefvec:
++      b       undefvec
++swivec:
++      b       swivec
++pabtvec:
++      b       pabtvec
++dabtvec:
++      b       dabtvec
++rsvdvec:
++      b       rsvdvec
++irqvec:
++      b       irqvec
++fiqvec:
++      b       fiqvec
++
++reset:
++      /*
++       * set the cpu to SVC32 mode
++       */
++      mrs     r0,cpsr
++      bic     r0,r0,#0x1f
++      orr     r0,r0,#0xd3
++      msr     cpsr,r0
++
++/* turn off the watchdog */
++#define pWTCON                0x53000000
++#define INTMSK                0x4A000008      /* Interupt-Controller base addresses */
++#define INTSUBMSK     0x4A00001C
++#define CLKDIVN       0x4C000014      /* clock divisor register */
++
++      ldr     r0, =pWTCON
++      mov     r1, #0x0
++      str     r1, [r0]
++
++      mov     r1, #0xffffffff
++      ldr     r0, =INTMSK
++      str     r1, [r0]
++      ldr     r1, =0x3ff
++      ldr     r0, =INTSUBMSK
++      str     r1, [r0]
++
++      /* FCLK:HCLK:PCLK = 1:2:4 */
++      /* default FCLK is 120 MHz ! */
++      ldr     r0, =CLKDIVN
++      mov     r1, #3
++      str     r1, [r0]
++
++      bl      cpu_init_crit
++      ldr     r0,=TEXT_BASE
++      mov     pc, r0
++
++cpu_init_crit:
++      /*
++       * flush v4 I/D caches
++       */
++      mov     r0, #0
++      mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
++      mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
++
++      /*
++       * 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
++
++      /*
++       * before relocating, we have to setup RAM timing
++       * because memory timing is board-dependend, you will
++       * find a lowlevel_init.S in your board directory.
++       */
++      mov     ip, lr
++      bl      lowlevel_init
++      mov     lr, ip
++      mov     pc, lr
++
+Index: u-boot/board/smdk2440/lowlevel_foo.lds
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2440/lowlevel_foo.lds
+@@ -0,0 +1,56 @@
++/*
++ * (C) Copyright 2002
++ * Gary Jennejohn, DENX Software Engineering, <gj@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      :
++      {
++        lowlevel_foo.o (.text)
++        *(.text)
++      }
++
++      . = ALIGN(4);
++      .rodata : { *(.rodata) }
++
++      . = ALIGN(4);
++      .data : { *(.data) }
++
++      . = ALIGN(4);
++      .got : { *(.got) }
++
++      . = .;
++      __u_boot_cmd_start = .;
++      .u_boot_cmd : { *(.u_boot_cmd) }
++      __u_boot_cmd_end = .;
++
++      . = ALIGN(4);
++      __bss_start = .;
++      .bss : { *(.bss) }
++      _end = .;
++}
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-smdk2443.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-smdk2443.patch
new file mode 100644 (file)
index 0000000..5757cc0
--- /dev/null
@@ -0,0 +1,1411 @@
+Index: u-boot/Makefile
+===================================================================
+--- u-boot.orig/Makefile
++++ u-boot/Makefile
+@@ -2045,6 +2045,9 @@
+ smdk2440_config :     unconfig
+       @$(MKCONFIG) $(@:_config=) arm arm920t smdk2440 NULL s3c24x0
++smdk2443_config :     unconfig
++      @$(MKCONFIG) $(@:_config=) arm arm920t smdk2443 NULL s3c24x0
++
+ SX1_config :          unconfig
+       @$(MKCONFIG) $(@:_config=) arm arm925t sx1
+Index: u-boot/board/smdk2443/Makefile
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2443/Makefile
+@@ -0,0 +1,67 @@
++#
++# (C) Copyright 2000-2006
++# Wolfgang Denk, DENX Software Engineering, wd@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
++#
++
++include $(TOPDIR)/config.mk
++
++LIB   = $(obj)lib$(BOARD).a
++
++COBJS := smdk2443.o flash.o udc.o
++SOBJS := lowlevel_init.o
++
++.PHONY:       all
++
++all:  $(LIB) lowlevel_foo.bin
++
++SRCS  := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS  := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB):       $(obj).depend $(OBJS) $(SOBJS)
++      $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
++
++lowlevel_foo.o:       lowlevel_foo.S
++      $(CC) -c -DTEXT_BASE=0x33F80000 -march=armv4 \
++        -o lowlevel_foo.o lowlevel_foo.S
++
++lowlevel_foo: lowlevel_foo.o lowlevel_init.o lowlevel_foo.lds
++      $(LD) -T ./lowlevel_foo.lds -Ttext 0x33f80000 -Bstatic \
++        lowlevel_init.o lowlevel_foo.o -o lowlevel_foo
++
++lowlevel_foo.bin:     lowlevel_foo
++      $(CROSS_COMPILE)objcopy --gap-fill=0xff -O binary \
++        lowlevel_foo lowlevel_foo.bin
++
++clean:
++      rm -f $(SOBJS) $(OBJS)
++
++distclean:    clean
++      rm -f $(LIB) core *.bak .depend
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+Index: u-boot/board/smdk2443/smdk2443.c
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2443/smdk2443.c
+@@ -0,0 +1,147 @@
++/*
++ * (C) Copyright 2006 OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * 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 <s3c2440.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#define FCLK_SPEED 1
++
++#if FCLK_SPEED==0             /* Fout = 203MHz, Fin = 12MHz for Audio */
++#define M_MDIV        0xC3
++#define M_PDIV        0x4
++#define M_SDIV        0x1
++#elif FCLK_SPEED==1           /* Fout = 399.65MHz */
++#define M_MDIV        0x6e
++#define M_PDIV        0x3
++#define M_SDIV        0x1
++#endif
++
++#define USB_CLOCK 1
++
++#if USB_CLOCK==0
++#define U_M_MDIV      0xA1
++#define U_M_PDIV      0x3
++#define U_M_SDIV      0x1
++#elif USB_CLOCK==1
++#define U_M_MDIV      0x3c
++#define U_M_PDIV      0x4
++#define U_M_SDIV      0x2
++#endif
++
++static inline void delay (unsigned long loops)
++{
++      __asm__ volatile ("1:\n"
++        "subs %0, %1, #1\n"
++        "bne 1b":"=r" (loops):"0" (loops));
++}
++
++/*
++ * Miscellaneous platform dependent initialisations
++ */
++
++int board_init (void)
++{
++      S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++      /* to reduce PLL lock time, adjust the LOCKTIME register */
++      clk_power->LOCKTIME = 0xFFFFFF;
++
++      /* configure MPLL */
++      clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
++
++      /* some delay between MPLL and UPLL */
++      delay (4000);
++
++      /* configure UPLL */
++      clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
++
++      /* some delay between MPLL and UPLL */
++      delay (8000);
++
++      /* set up the I/O ports */
++      gpio->GPACON = 0x007FFFFF;
++      gpio->GPBCON = 0x00044555;
++      gpio->GPBUP = 0x000007FF;
++      gpio->GPCCON = 0xAAAAAAAA;
++      gpio->GPCUP = 0x0000FFFF;
++      gpio->GPDCON = 0xAAAAAAAA;
++      gpio->GPDUP = 0x0000FFFF;
++      gpio->GPECON = 0xAAAAAAAA;
++      gpio->GPEUP = 0x0000FFFF;
++      gpio->GPFCON = 0x000055AA;
++      gpio->GPFUP = 0x000000FF;
++      gpio->GPGCON = 0xFD95FFBA;
++      gpio->GPGUP = 0x0000FFFF;
++#ifdef CONFIG_SERIAL3
++      gpio->GPHCON = 0x002AAAAA;
++#else
++      gpio->GPHCON = 0x002AFAAA;
++#endif
++      gpio->GPHUP = 0x000007FF;
++
++#if 0
++      /* USB Device Part */
++      /*GPGCON is reset for USB Device */
++      gpio->GPGCON = (gpio->GPGCON & ~(3 << 24)) | (1 << 24); /* Output Mode */
++      gpio->GPGUP = gpio->GPGUP | ( 1 << 12);                 /* Pull up disable */
++
++      gpio->GPGDAT |= ( 1 << 12) ;
++      gpio->GPGDAT &= ~( 1 << 12) ;
++      udelay(20000);
++      gpio->GPGDAT |= ( 1 << 12) ;
++#endif
++
++      /* arch number of SMDK2440-Board */
++      gd->bd->bi_arch_number = MACH_TYPE_S3C2440;
++
++      /* adress of boot parameters */
++      gd->bd->bi_boot_params = 0x30000100;
++
++      icache_enable();
++      dcache_enable();
++
++      return 0;
++}
++
++int dram_init (void)
++{
++      gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
++      gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
++
++      return 0;
++}
++
++/* The sum of all part_size[]s must equal to the NAND size, i.e., 0x4000000.
++   "initrd" is sized such that it can hold two uncompressed 16 bit 640*480
++   images: 640*480*2*2 = 1228800 < 1245184. */
++
++unsigned int dynpart_size[] = {
++    CFG_UBOOT_SIZE, 0x20000, 0x200000, 0xa0000, 0x3d5c000-CFG_UBOOT_SIZE, 0 };
++
++char *dynpart_names[] = {
++    "u-boot", "u-boot_env", "kernel", "splash", "rootfs", NULL };
++
++
+Index: u-boot/board/smdk2443/u-boot.lds
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2443/u-boot.lds
+@@ -0,0 +1,58 @@
++/*
++ * (C) Copyright 2002
++ * Gary Jennejohn, DENX Software Engineering, <gj@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_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
++OUTPUT_ARCH(arm)
++ENTRY(_start)
++SECTIONS
++{
++      . = 0x00000000;
++
++      . = ALIGN(4);
++      .text      :
++      {
++        cpu/arm920t/start.o   (.text)
++        cpu/arm920t/s3c24x0/nand_read.o (.text)
++        *(.text)
++      }
++
++      . = ALIGN(4);
++      .rodata : { *(.rodata) }
++
++      . = ALIGN(4);
++      .data : { *(.data) }
++
++      . = ALIGN(4);
++      .got : { *(.got) }
++
++      . = .;
++      __u_boot_cmd_start = .;
++      .u_boot_cmd : { *(.u_boot_cmd) }
++      __u_boot_cmd_end = .;
++
++      . = ALIGN(4);
++      __bss_start = .;
++      .bss : { *(.bss) }
++      _end = .;
++}
+Index: u-boot/include/configs/smdk2443.h
+===================================================================
+--- /dev/null
++++ u-boot/include/configs/smdk2443.h
+@@ -0,0 +1,289 @@
++/*
++ * (C) Copyright 2007 OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * Configuation settings for the SAMSUNG SMDK2443 board.
++ *
++ * 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
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#if 0
++/* If we want to start u-boot from usb bootloader in NOR flash */
++#define CONFIG_SKIP_RELOCATE_UBOOT    1
++#define       CONFIG_SKIP_LOWLEVEL_INIT       1
++#else
++/* If we want to start u-boot directly from within NAND flash */
++#define CONFIG_LL_INIT_NAND_ONLY
++#define CONFIG_S3C2410_NAND_BOOT      1
++#define CONFIG_S3C2410_NAND_SKIP_BAD  1
++#endif
++
++#define CFG_UBOOT_SIZE                0x40000 /* size of u-boot, for NAND loading */
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++#define CONFIG_ARM920T                1       /* This is an ARM920T Core      */
++#define       CONFIG_S3C2440          1       /* in a SAMSUNG S3C2440 SoC     */
++#define CONFIG_SMDK2443               1       /* on a SAMSUNG SMDK2440 Board  */
++
++/* input clock of PLL */
++#define CONFIG_SYS_CLK_FREQ   16934400/* SMDK2440 has 16.9344MHz input clock */
++
++
++#define USE_920T_MMU          1
++#define CONFIG_USE_IRQ                1
++
++/*
++ * Size of malloc() pool
++ */
++#define CFG_MALLOC_LEN                (CFG_ENV_SIZE + 2048*1024)
++#define CFG_GBL_DATA_SIZE     128     /* size in bytes reserved for initial data */
++
++/*
++ * Hardware drivers
++ */
++#define CONFIG_DRIVER_CS8900  1       /* we have a CS8900 on-board */
++#define CS8900_BASE           0x19000300
++#define CS8900_BUS16          1 /* the Linux driver does accesses as shorts */
++
++/*
++ * select serial console configuration
++ */
++#define CONFIG_SERIAL1          1     /* we use SERIAL 1 on SMDK2440 */
++#define CONFIG_HWFLOW         1
++
++/************************************************************
++ * RTC
++ ************************************************************/
++#define       CONFIG_RTC_S3C24X0      1
++
++/* allow to overwrite serial and ethaddr */
++#define CONFIG_ENV_OVERWRITE
++
++#define CONFIG_BAUDRATE               115200
++
++/***********************************************************
++ * Command definition
++ ***********************************************************/
++#define CONFIG_COMMANDS \
++                      (CONFIG_CMD_DFL  | \
++                      /*CFG_CMD_BSP    | */ \
++                      CFG_CMD_CACHE    | \
++                      CFG_CMD_DATE     | \
++                      /*CFG_CMD_DHCP   | */ \
++                      CFG_CMD_DIAG     | \
++                      CFG_CMD_ELF      | \
++                      CFG_CMD_EXT2     | \
++                      CFG_CMD_FAT      | \
++                      /*CFG_CMD_HWFLOW         | */ \
++                      /* CFG_CMD_IDE   | */ \
++                      /* CFG_CMD_IRQ   | */ \
++                      CFG_CMD_JFFS2    | \
++                      CFG_CMD_MMC      | \
++                      CFG_CMD_NAND     | \
++                      CFG_CMD_PING     | \
++                      CFG_CMD_PORTIO   | \
++                      CFG_CMD_REGINFO  | \
++                      CFG_CMD_SAVES    | \
++                      CFG_CMD_LICENSE  | \
++                      CFG_CMD_USB)
++
++/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
++#include <cmd_confdefs.h>
++
++#define CONFIG_BOOTDELAY      3
++#define CONFIG_BOOTARGS       "root=/dev/mtdblock4 rootfstype=jffs2 console=ttySAC2,115200 loglevel=8"
++#define CONFIG_ETHADDR                00:0c:20:02:0a:5b
++#define CONFIG_NETMASK          255.255.255.0
++#define CONFIG_IPADDR         192.168.1.100
++#define CONFIG_SERVERIP               192.168.1.21
++#define CONFIG_BOOTCOMMAND    "nand read.e 0x32000000 0x100000 0x200000; bootm"
++
++#define CONFIG_DOS_PARTITION  1
++
++#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
++#define CONFIG_KGDB_BAUDRATE  115200          /* speed to run kgdb serial port */
++/* what's this ? it's not used anywhere */
++#define CONFIG_KGDB_SER_INDEX 1               /* which serial port to use */
++#endif
++
++/*
++ * Miscellaneous configurable options
++ */
++#define       CFG_LONGHELP                            /* undef to save memory         */
++#define       CFG_PROMPT              "SMDK2443 # "   /* Monitor Command Prompt       */
++#define       CFG_CBSIZE              256             /* Console I/O Buffer Size      */
++#define       CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
++#define       CFG_MAXARGS             32              /* max number of command args   */
++#define CFG_BARGSIZE          CFG_CBSIZE      /* Boot Argument Buffer Size    */
++
++#define CFG_MEMTEST_START     0x30000000      /* memtest works on     */
++#define CFG_MEMTEST_END               0x33F00000      /* 63 MB in DRAM        */
++
++#undef  CFG_CLKS_IN_HZ                /* everything, incl board info, in Hz */
++
++#define       CFG_LOAD_ADDR           0x32000000      /* default load address */
++
++/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
++/* it to wrap 100 times (total 1562500) to get 1 sec. */
++#define       CFG_HZ                  1562500
++
++/* valid baudrates */
++#define CFG_BAUDRATE_TABLE    { 9600, 19200, 38400, 57600, 115200 }
++
++/*-----------------------------------------------------------------------
++ * Stack sizes
++ *
++ * The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE      (512*1024)      /* regular stack */
++#ifdef CONFIG_USE_IRQ
++#define CONFIG_STACKSIZE_IRQ  (8*1024)        /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ  (4*1024)        /* FIQ stack */
++#endif
++
++/* IDE/ATA config */
++
++#if 0
++#define CFG_IDE_MAXBUS                1
++#define CFG_IDE_MAXDEVICE     2
++#define CFG_IDE_PREINIT               0
++
++#define CFG_ATA_BASE_ADDR
++#endif
++
++#define CONFIG_USB_OHCI               1
++
++#define CONFIG_USB_DEVICE     1
++#define CONFIG_USB_TTY                1
++#define CFG_CONSOLE_IS_IN_ENV 1
++#define CONFIG_USBD_VENDORID          0x1457     /* Linux/NetChip */
++#define CONFIG_USBD_PRODUCTID_GSERIAL 0x5120    /* gserial */
++#define CONFIG_USBD_PRODUCTID_CDCACM  0x5119    /* CDC ACM */
++#define CONFIG_USBD_MANUFACTURER      "FiWin"
++#define CONFIG_USBD_PRODUCT_NAME      "S3C2443 Bootloader " U_BOOT_VERSION
++#define CONFIG_EXTRA_ENV_SETTINGS     "usbtty=cdc_acm\0"
++#define CONFIG_USBD_DFU                       1
++#define CONFIG_USBD_DFU_XFER_SIZE     4096
++#define CONFIG_USBD_DFU_INTERFACE     2
++
++/*-----------------------------------------------------------------------
++ * Physical Memory Map
++ */
++#define CONFIG_NR_DRAM_BANKS  1          /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1          0x30000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE     0x04000000 /* 64 MB */
++
++#define PHYS_FLASH_1          0x00000000 /* Flash Bank #1 */
++
++#define CFG_FLASH_BASE                PHYS_FLASH_1
++
++/*-----------------------------------------------------------------------
++ * FLASH and environment organization
++ */
++
++#define CONFIG_AMD_LV400      1       /* uncomment this if you have a LV400 flash */
++#if 0
++#define CONFIG_AMD_LV800      1       /* uncomment this if you have a LV800 flash */
++#endif
++
++#define CFG_MAX_FLASH_BANKS   1       /* max number of memory banks */
++#ifdef CONFIG_AMD_LV800
++#define PHYS_FLASH_SIZE               0x00100000 /* 1MB */
++#define CFG_MAX_FLASH_SECT    (19)    /* max number of sectors on one chip */
++#define CFG_ENV_ADDR          (CFG_FLASH_BASE + 0x0F0000) /* addr of environment */
++#endif
++#ifdef CONFIG_AMD_LV400
++#define PHYS_FLASH_SIZE               0x00080000 /* 512KB */
++#define CFG_MAX_FLASH_SECT    (11)    /* max number of sectors on one chip */
++#define CFG_ENV_ADDR          (CFG_FLASH_BASE + 0x070000) /* addr of environment */
++#endif
++
++/* timeout values are in ticks */
++#define CFG_FLASH_ERASE_TOUT  (5*CFG_HZ) /* Timeout for Flash Erase */
++#define CFG_FLASH_WRITE_TOUT  (5*CFG_HZ) /* Timeout for Flash Write */
++
++#define       CFG_ENV_IS_IN_NAND      1
++#define CFG_ENV_SIZE          0x20000         /* 128k Total Size of Environment Sector */
++#define CFG_ENV_OFFSET_OOB    1
++#define CFG_PREBOOT_OVERRIDE  1
++
++#define NAND_MAX_CHIPS                1
++#define CFG_NAND_BASE         0x4e000000
++#define CFG_MAX_NAND_DEVICE   1
++
++#define CONFIG_MMC            1
++#define CFG_MMC_BASE          0xff000000
++
++#define CONFIG_EXT2           1
++
++/* FAT driver in u-boot is broken currently */
++#define CONFIG_FAT            1
++#define CONFIG_SUPPORT_VFAT
++
++#if 1
++/* JFFS2 driver */
++#define CONFIG_JFFS2_CMDLINE  1
++#define CONFIG_JFFS2_NAND     1
++#define CONFIG_JFFS2_NAND_DEV 0
++//#define CONFIG_JFFS2_NAND_OFF               0x634000
++//#define CONFIG_JFFS2_NAND_SIZE      0x39cc000
++#endif
++
++/* ATAG configuration */
++#define CONFIG_INITRD_TAG             1
++#define CONFIG_SETUP_MEMORY_TAGS      1
++#define CONFIG_CMDLINE_TAG            1
++#if 0
++#define CONFIG_SERIAL_TAG             1
++#define CONFIG_REVISION_TAG           1
++#endif
++
++
++#if 0
++#define CONFIG_VIDEO
++#define CONFIG_VIDEO_S3C2410
++#define CONFIG_CFB_CONSOLE
++#define CONFIG_VIDEO_LOGO
++#define CONFIG_VGA_AS_SINGLE_DEVICE
++
++#define VIDEO_KBD_INIT_FCT    0
++#define VIDEO_TSTC_FCT                serial_tstc
++#define VIDEO_GETC_FCT                serial_getc
++
++#define LCD_VIDEO_ADDR                0x33d00000
++#endif
++
++#define CONFIG_S3C2410_NAND_BBT               1
++//#define CONFIG_S3C2410_NAND_HWECC   1
++
++#define CFG_NAND_YAFFS_WRITE
++#define CFG_NAND_YAFFS1_NEW_OOB_LAYOUT
++
++#define MTDIDS_DEFAULT                "nand0=smdk2443-nand"
++#define MTPARTS_DEFAULT               "smdk2443-nand:0x00100000(u-boot),0x00200000(kernel),0x00200000(update),0x00100000(splash),0x01400000(jffs2),-(temp)"
++#define CFG_NAND_DYNPART_MTD_KERNEL_NAME "smdk2443-nand"
++#define CONFIG_NAND_DYNPART
++
++#endif        /* __CONFIG_H */
+Index: u-boot/board/smdk2443/lowlevel_foo.S
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2443/lowlevel_foo.S
+@@ -0,0 +1,82 @@
++
++_start:
++      b       reset
++undefvec:
++      b       undefvec
++swivec:
++      b       swivec
++pabtvec:
++      b       pabtvec
++dabtvec:
++      b       dabtvec
++rsvdvec:
++      b       rsvdvec
++irqvec:
++      b       irqvec
++fiqvec:
++      b       fiqvec
++
++reset:
++      /*
++       * set the cpu to SVC32 mode
++       */
++      mrs     r0,cpsr
++      bic     r0,r0,#0x1f
++      orr     r0,r0,#0xd3
++      msr     cpsr,r0
++
++/* turn off the watchdog */
++#define pWTCON                0x53000000
++#define INTMSK                0x4A000008      /* Interupt-Controller base addresses */
++#define INTSUBMSK     0x4A00001C
++#define CLKDIVN       0x4C000014      /* clock divisor register */
++
++      ldr     r0, =pWTCON
++      mov     r1, #0x0
++      str     r1, [r0]
++
++      mov     r1, #0xffffffff
++      ldr     r0, =INTMSK
++      str     r1, [r0]
++      ldr     r1, =0x3ff
++      ldr     r0, =INTSUBMSK
++      str     r1, [r0]
++
++      /* FCLK:HCLK:PCLK = 1:2:4 */
++      /* default FCLK is 120 MHz ! */
++      ldr     r0, =CLKDIVN
++      mov     r1, #3
++      str     r1, [r0]
++
++      bl      cpu_init_crit
++      ldr     r0,=TEXT_BASE
++      mov     pc, r0
++
++cpu_init_crit:
++      /*
++       * flush v4 I/D caches
++       */
++      mov     r0, #0
++      mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
++      mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
++
++      /*
++       * 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
++
++      /*
++       * before relocating, we have to setup RAM timing
++       * because memory timing is board-dependend, you will
++       * find a lowlevel_init.S in your board directory.
++       */
++      mov     ip, lr
++      bl      lowlevel_init
++      mov     lr, ip
++      mov     pc, lr
++
+Index: u-boot/board/smdk2443/lowlevel_init.S
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2443/lowlevel_init.S
+@@ -0,0 +1,163 @@
++/*
++ * SMDK2443 Memory Setup
++ *
++ * Copyright (C) 2007 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge@openmoko.org>
++ *
++ * 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 <version.h>
++
++
++/* some parameters for the board */
++
++/*
++ *
++ * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
++ *
++ * Copyright (C) 2002 Samsung Electronics SW.LEE  <hitchcar@sec.samsung.com>
++ *
++ */
++
++#define BWSCON        0x48000000
++
++/* BWSCON */
++#define DW8                   (0x0)
++#define DW16                  (0x1)
++#define DW32                  (0x2)
++#define WAIT                  (0x1<<2)
++#define UBLB                  (0x1<<3)
++
++#define B1_BWSCON             (DW32)
++#define B2_BWSCON             (DW16)
++#define B3_BWSCON             (DW16 + WAIT + UBLB)
++#define B4_BWSCON             (DW16)
++#define B5_BWSCON             (DW16)
++#define B6_BWSCON             (DW32)
++#define B7_BWSCON             (DW32)
++
++/* BANK0CON */
++#define B0_Tacs                       0x0     /*  0clk */
++#define B0_Tcos                       0x0     /*  0clk */
++#define B0_Tacc                       0x7     /* 14clk */
++#define B0_Tcoh                       0x0     /*  0clk */
++#define B0_Tah                        0x0     /*  0clk */
++#define B0_Tacp                       0x0
++#define B0_PMC                        0x0     /* normal */
++
++/* BANK1CON */
++#define B1_Tacs                       0x0     /*  0clk */
++#define B1_Tcos                       0x0     /*  0clk */
++#define B1_Tacc                       0x7     /* 14clk */
++#define B1_Tcoh                       0x0     /*  0clk */
++#define B1_Tah                        0x0     /*  0clk */
++#define B1_Tacp                       0x0
++#define B1_PMC                        0x0
++
++#define B2_Tacs                       0x0
++#define B2_Tcos                       0x0
++#define B2_Tacc                       0x7
++#define B2_Tcoh                       0x0
++#define B2_Tah                        0x0
++#define B2_Tacp                       0x0
++#define B2_PMC                        0x0
++
++#define B3_Tacs                       0x0     /*  0clk */
++#define B3_Tcos                       0x3     /*  4clk */
++#define B3_Tacc                       0x7     /* 14clk */
++#define B3_Tcoh                       0x1     /*  1clk */
++#define B3_Tah                        0x0     /*  0clk */
++#define B3_Tacp                       0x3     /*  6clk */
++#define B3_PMC                        0x0     /* normal */
++
++#define B4_Tacs                       0x0     /*  0clk */
++#define B4_Tcos                       0x0     /*  0clk */
++#define B4_Tacc                       0x7     /* 14clk */
++#define B4_Tcoh                       0x0     /*  0clk */
++#define B4_Tah                        0x0     /*  0clk */
++#define B4_Tacp                       0x0
++#define B4_PMC                        0x0     /* normal */
++
++#define B5_Tacs                       0x0     /*  0clk */
++#define B5_Tcos                       0x0     /*  0clk */
++#define B5_Tacc                       0x7     /* 14clk */
++#define B5_Tcoh                       0x0     /*  0clk */
++#define B5_Tah                        0x0     /*  0clk */
++#define B5_Tacp                       0x0
++#define B5_PMC                        0x0     /* normal */
++
++#define B6_MT                 0x3     /* SDRAM */
++#define B6_Trcd                       0x1
++#define B6_SCAN                       0x1     /* 9bit */
++
++#define B7_MT                 0x3     /* SDRAM */
++#define B7_Trcd                       0x1     /* 3clk */
++#define B7_SCAN                       0x1     /* 9bit */
++
++/* REFRESH parameter */
++#define REFEN                 0x1     /* Refresh enable */
++#define TREFMD                        0x0     /* CBR(CAS before RAS)/Auto refresh */
++#define Trp                   0x0     /* 2clk */
++#define Trc                   0x3     /* 7clk */
++#define Tchr                  0x2     /* 3clk */
++#define REFCNT                        1113    /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
++/**************************************/
++
++_TEXT_BASE:
++      .word   TEXT_BASE
++
++.globl lowlevel_init
++lowlevel_init:
++      /* memory control configuration */
++      /* make r0 relative the current location so that it */
++      /* reads SMRDATA out of FLASH rather than memory ! */
++      ldr     r0, =SMRDATA
++      ldr     r1, _TEXT_BASE
++      sub     r0, r0, r1
++      ldr     r1, =BWSCON     /* Bus Width Status Controller */
++      add     r2, r0, #13*4
++0:
++      ldr     r3, [r0], #4
++      str     r3, [r1], #4
++      cmp     r2, r0
++      bne     0b
++
++      /* everything is fine now */
++      mov     pc, lr
++
++      .ltorg
++/* the literal pools origin */
++
++SMRDATA:
++    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
++    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
++    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
++    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
++    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
++    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
++    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
++    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
++    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
++    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
++    .word 0x32
++    .word 0x30
++    .word 0x30
+Index: u-boot/board/smdk2443/config.mk
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2443/config.mk
+@@ -0,0 +1,29 @@
++#
++# (C) Copyright 2002
++# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
++# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
++#
++# SAMSUNG SMDK2443 board with S3C2443 (ARM920T) cpu
++#
++# see http://www.samsung.com/ for more information on SAMSUNG
++#
++
++CONFIG_USB_DFU_VENDOR=0x1457
++CONFIG_USB_DFU_PRODUCT=0x511c
++CONFIG_USB_DFU_REVISION=0x0100
++
++#
++# SMDK2443 has 1 bank of 64 MB DRAM
++#
++# 3000'0000 to 3400'0000
++#
++# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
++# optionally with a ramdisk at 3080'0000
++#
++# we load ourself to 33F8'0000
++#
++# download area is 3300'0000
++#
++
++
++TEXT_BASE = 0x33F80000
+Index: u-boot/board/smdk2443/lowlevel_foo.lds
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2443/lowlevel_foo.lds
+@@ -0,0 +1,56 @@
++/*
++ * (C) Copyright 2002
++ * Gary Jennejohn, DENX Software Engineering, <gj@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      :
++      {
++        lowlevel_foo.o (.text)
++        *(.text)
++      }
++
++      . = ALIGN(4);
++      .rodata : { *(.rodata) }
++
++      . = ALIGN(4);
++      .data : { *(.data) }
++
++      . = ALIGN(4);
++      .got : { *(.got) }
++
++      . = .;
++      __u_boot_cmd_start = .;
++      .u_boot_cmd : { *(.u_boot_cmd) }
++      __u_boot_cmd_end = .;
++
++      . = ALIGN(4);
++      __bss_start = .;
++      .bss : { *(.bss) }
++      _end = .;
++}
+Index: u-boot/board/smdk2443/flash.c
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2443/flash.c
+@@ -0,0 +1,433 @@
++/*
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Alex Zuepke <azu@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>
++
++ulong myflush (void);
++
++
++#define FLASH_BANK_SIZE       PHYS_FLASH_SIZE
++#define MAIN_SECT_SIZE  0x10000       /* 64 KB */
++
++flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
++
++
++#define CMD_READ_ARRAY                0x000000F0
++#define CMD_UNLOCK1           0x000000AA
++#define CMD_UNLOCK2           0x00000055
++#define CMD_ERASE_SETUP               0x00000080
++#define CMD_ERASE_CONFIRM     0x00000030
++#define CMD_PROGRAM           0x000000A0
++#define CMD_UNLOCK_BYPASS     0x00000020
++
++#define MEM_FLASH_ADDR1               (*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555 << 1)))
++#define MEM_FLASH_ADDR2               (*(volatile u16 *)(CFG_FLASH_BASE + (0x000002AA << 1)))
++
++#define BIT_ERASE_DONE                0x00000080
++#define BIT_RDY_MASK          0x00000080
++#define BIT_PROGRAM_ERROR     0x00000020
++#define BIT_TIMEOUT           0x80000000      /* our flag */
++
++#define READY 1
++#define ERR   2
++#define TMO   4
++
++/*-----------------------------------------------------------------------
++ */
++
++ulong flash_init (void)
++{
++      int i, j;
++      ulong size = 0;
++
++      for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
++              ulong flashbase = 0;
++
++              flash_info[i].flash_id =
++#if defined(CONFIG_AMD_LV400)
++                      (AMD_MANUFACT & FLASH_VENDMASK) |
++                      (AMD_ID_LV400B & FLASH_TYPEMASK);
++#elif defined(CONFIG_AMD_LV800)
++                      (AMD_MANUFACT & FLASH_VENDMASK) |
++                      (AMD_ID_LV800B & FLASH_TYPEMASK);
++#else
++#error "Unknown flash configured"
++#endif
++                      flash_info[i].size = FLASH_BANK_SIZE;
++              flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
++              memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
++              if (i == 0)
++                      flashbase = PHYS_FLASH_1;
++              else
++                      panic ("configured too many flash banks!\n");
++              for (j = 0; j < flash_info[i].sector_count; j++) {
++                      if (j <= 3) {
++                              /* 1st one is 16 KB */
++                              if (j == 0) {
++                                      flash_info[i].start[j] =
++                                              flashbase + 0;
++                              }
++
++                              /* 2nd and 3rd are both 8 KB */
++                              if ((j == 1) || (j == 2)) {
++                                      flash_info[i].start[j] =
++                                              flashbase + 0x4000 + (j -
++                                                                    1) *
++                                              0x2000;
++                              }
++
++                              /* 4th 32 KB */
++                              if (j == 3) {
++                                      flash_info[i].start[j] =
++                                              flashbase + 0x8000;
++                              }
++                      } else {
++                              flash_info[i].start[j] =
++                                      flashbase + (j - 3) * MAIN_SECT_SIZE;
++                      }
++              }
++              size += flash_info[i].size;
++      }
++
++      flash_protect (FLAG_PROTECT_SET,
++                     CFG_FLASH_BASE,
++                     CFG_FLASH_BASE + monitor_flash_len - 1,
++                     &flash_info[0]);
++
++      flash_protect (FLAG_PROTECT_SET,
++                     CFG_ENV_ADDR,
++                     CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
++
++      return size;
++}
++
++/*-----------------------------------------------------------------------
++ */
++void flash_print_info (flash_info_t * info)
++{
++      int i;
++
++      switch (info->flash_id & FLASH_VENDMASK) {
++      case (AMD_MANUFACT & FLASH_VENDMASK):
++              printf ("AMD: ");
++              break;
++      default:
++              printf ("Unknown Vendor ");
++              break;
++      }
++
++      switch (info->flash_id & FLASH_TYPEMASK) {
++      case (AMD_ID_LV400B & FLASH_TYPEMASK):
++              printf ("1x Amd29LV400BB (4Mbit)\n");
++              break;
++      case (AMD_ID_LV800B & FLASH_TYPEMASK):
++              printf ("1x Amd29LV800BB (8Mbit)\n");
++              break;
++      default:
++              printf ("Unknown Chip Type\n");
++              goto Done;
++              break;
++      }
++
++      printf ("  Size: %ld MB in %d Sectors\n",
++              info->size >> 20, info->sector_count);
++
++      printf ("  Sector Start Addresses:");
++      for (i = 0; i < info->sector_count; i++) {
++              if ((i % 5) == 0) {
++                      printf ("\n   ");
++              }
++              printf (" %08lX%s", info->start[i],
++                      info->protect[i] ? " (RO)" : "     ");
++      }
++      printf ("\n");
++
++      Done:;
++}
++
++/*-----------------------------------------------------------------------
++ */
++
++int flash_erase (flash_info_t * info, int s_first, int s_last)
++{
++      ushort result;
++      int iflag, cflag, prot, sect;
++      int rc = ERR_OK;
++      int chip;
++
++      /* first look for protection bits */
++
++      if (info->flash_id == FLASH_UNKNOWN)
++              return ERR_UNKNOWN_FLASH_TYPE;
++
++      if ((s_first < 0) || (s_first > s_last)) {
++              return ERR_INVAL;
++      }
++
++      if ((info->flash_id & FLASH_VENDMASK) !=
++          (AMD_MANUFACT & FLASH_VENDMASK)) {
++              return ERR_UNKNOWN_FLASH_VENDOR;
++      }
++
++      prot = 0;
++      for (sect = s_first; sect <= s_last; ++sect) {
++              if (info->protect[sect]) {
++                      prot++;
++              }
++      }
++      if (prot)
++              return ERR_PROTECTED;
++
++      /*
++       * Disable interrupts which might cause a timeout
++       * here. Remember that our exception vectors are
++       * at address 0 in the flash, and we don't want a
++       * (ticker) exception to happen while the flash
++       * chip is in programming mode.
++       */
++      cflag = icache_status ();
++      icache_disable ();
++      iflag = disable_interrupts ();
++
++      /* Start erase on unprotected sectors */
++      for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
++              printf ("Erasing sector %2d ... ", sect);
++
++              /* arm simple, non interrupt dependent timer */
++              reset_timer_masked ();
++
++              if (info->protect[sect] == 0) { /* not protected */
++                      vu_short *addr = (vu_short *) (info->start[sect]);
++
++                      MEM_FLASH_ADDR1 = CMD_UNLOCK1;
++                      MEM_FLASH_ADDR2 = CMD_UNLOCK2;
++                      MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
++
++                      MEM_FLASH_ADDR1 = CMD_UNLOCK1;
++                      MEM_FLASH_ADDR2 = CMD_UNLOCK2;
++                      *addr = CMD_ERASE_CONFIRM;
++
++                      /* wait until flash is ready */
++                      chip = 0;
++
++                      do {
++                              result = *addr;
++
++                              /* check timeout */
++                              if (get_timer_masked () >
++                                  CFG_FLASH_ERASE_TOUT) {
++                                      MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
++                                      chip = TMO;
++                                      break;
++                              }
++
++                              if (!chip
++                                  && (result & 0xFFFF) & BIT_ERASE_DONE)
++                                      chip = READY;
++
++                              if (!chip
++                                  && (result & 0xFFFF) & BIT_PROGRAM_ERROR)
++                                      chip = ERR;
++
++                      } while (!chip);
++
++                      MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
++
++                      if (chip == ERR) {
++                              rc = ERR_PROG_ERROR;
++                              goto outahere;
++                      }
++                      if (chip == TMO) {
++                              rc = ERR_TIMOUT;
++                              goto outahere;
++                      }
++
++                      printf ("ok.\n");
++              } else {        /* it was protected */
++
++                      printf ("protected!\n");
++              }
++      }
++
++      if (ctrlc ())
++              printf ("User Interrupt!\n");
++
++      outahere:
++      /* allow flash to settle - wait 10 ms */
++      udelay_masked (10000);
++
++      if (iflag)
++              enable_interrupts ();
++
++      if (cflag)
++              icache_enable ();
++
++      return rc;
++}
++
++/*-----------------------------------------------------------------------
++ * Copy memory to flash
++ */
++
++volatile static int write_hword (flash_info_t * info, ulong dest, ushort data)
++{
++      vu_short *addr = (vu_short *) dest;
++      ushort result;
++      int rc = ERR_OK;
++      int cflag, iflag;
++      int chip;
++
++      /*
++       * Check if Flash is (sufficiently) erased
++       */
++      result = *addr;
++      if ((result & data) != data)
++              return ERR_NOT_ERASED;
++
++
++      /*
++       * Disable interrupts which might cause a timeout
++       * here. Remember that our exception vectors are
++       * at address 0 in the flash, and we don't want a
++       * (ticker) exception to happen while the flash
++       * chip is in programming mode.
++       */
++      cflag = icache_status ();
++      icache_disable ();
++      iflag = disable_interrupts ();
++
++      MEM_FLASH_ADDR1 = CMD_UNLOCK1;
++      MEM_FLASH_ADDR2 = CMD_UNLOCK2;
++      MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
++      *addr = CMD_PROGRAM;
++      *addr = data;
++
++      /* arm simple, non interrupt dependent timer */
++      reset_timer_masked ();
++
++      /* wait until flash is ready */
++      chip = 0;
++      do {
++              result = *addr;
++
++              /* check timeout */
++              if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
++                      chip = ERR | TMO;
++                      break;
++              }
++              if (!chip && ((result & 0x80) == (data & 0x80)))
++                      chip = READY;
++
++              if (!chip && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) {
++                      result = *addr;
++
++                      if ((result & 0x80) == (data & 0x80))
++                              chip = READY;
++                      else
++                              chip = ERR;
++              }
++
++      } while (!chip);
++
++      *addr = CMD_READ_ARRAY;
++
++      if (chip == ERR || *addr != data)
++              rc = ERR_PROG_ERROR;
++
++      if (iflag)
++              enable_interrupts ();
++
++      if (cflag)
++              icache_enable ();
++
++      return rc;
++}
++
++/*-----------------------------------------------------------------------
++ * Copy memory to flash.
++ */
++
++int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
++{
++      ulong cp, wp;
++      int l;
++      int i, rc;
++      ushort data;
++
++      wp = (addr & ~1);       /* get lower word aligned address */
++
++      /*
++       * handle unaligned start bytes
++       */
++      if ((l = addr - wp) != 0) {
++              data = 0;
++              for (i = 0, cp = wp; i < l; ++i, ++cp) {
++                      data = (data >> 8) | (*(uchar *) cp << 8);
++              }
++              for (; i < 2 && cnt > 0; ++i) {
++                      data = (data >> 8) | (*src++ << 8);
++                      --cnt;
++                      ++cp;
++              }
++              for (; cnt == 0 && i < 2; ++i, ++cp) {
++                      data = (data >> 8) | (*(uchar *) cp << 8);
++              }
++
++              if ((rc = write_hword (info, wp, data)) != 0) {
++                      return (rc);
++              }
++              wp += 2;
++      }
++
++      /*
++       * handle word aligned part
++       */
++      while (cnt >= 2) {
++              data = *((vu_short *) src);
++              if ((rc = write_hword (info, wp, data)) != 0) {
++                      return (rc);
++              }
++              src += 2;
++              wp += 2;
++              cnt -= 2;
++      }
++
++      if (cnt == 0) {
++              return ERR_OK;
++      }
++
++      /*
++       * handle unaligned tail bytes
++       */
++      data = 0;
++      for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
++              data = (data >> 8) | (*src++ << 8);
++              --cnt;
++      }
++      for (; i < 2; ++i, ++cp) {
++              data = (data >> 8) | (*(uchar *) cp << 8);
++      }
++
++      return write_hword (info, wp, data);
++}
+Index: u-boot/board/smdk2443/udc.c
+===================================================================
+--- /dev/null
++++ u-boot/board/smdk2443/udc.c
+@@ -0,0 +1,23 @@
++
++#include <common.h>
++#include <usbdcore.h>
++#include <s3c2440.h>
++
++void udc_ctrl(enum usbd_event event, int param)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++      switch (event) {
++      case UDC_CTRL_PULLUP_ENABLE:
++              if (param)
++                      gpio->GPGDAT |= (1 << 12);
++              else
++                      gpio->GPGDAT &= ~(1 << 12);
++              break;
++      case UDC_CTRL_500mA_ENABLE:
++              /* IGNORE */
++              break;
++      default:
++              break;
++      }
++}
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-strtoul.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-strtoul.patch
new file mode 100644 (file)
index 0000000..a88e94b
--- /dev/null
@@ -0,0 +1,43 @@
+Make simple_strtoul work with upper-case hex numbers.
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+
+Index: u-boot/lib_generic/vsprintf.c
+===================================================================
+--- u-boot.orig/lib_generic/vsprintf.c
++++ u-boot/lib_generic/vsprintf.c
+@@ -25,21 +25,22 @@ unsigned long simple_strtoul(const char 
+ {
+       unsigned long result = 0,value;
+-      if (*cp == '0') {
+-              cp++;
+-              if ((*cp == 'x') && isxdigit(cp[1])) {
+-                      base = 16;
+-                      cp++;
+-              }
+-              if (!base) {
+-                      base = 8;
+-              }
+-      }
+       if (!base) {
+               base = 10;
++              if (*cp == '0') {
++                      base = 8;
++                      cp++;
++                      if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
++                              cp++;
++                              base = 16;
++                      }
++              }
++      } else if (base == 16) {
++              if (cp[0] == '0' && toupper(cp[1]) == 'X')
++                      cp += 2;
+       }
+-      while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
+-          ? toupper(*cp) : *cp)-'A'+10) < base) {
++      while (isxdigit(*cp) &&
++             (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
+               result = result*base + value;
+               cp++;
+       }
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-usbtty-acm.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-usbtty-acm.patch
new file mode 100644 (file)
index 0000000..722a227
--- /dev/null
@@ -0,0 +1,1607 @@
+This patch adds cdc_acm interoperability to u-boot usbtty.
+
+It was taken (almost blindly) from the Linux for Siemens SX1 project on
+handhelds.org.  Please don't complain to me about coding style issues
+or whitespace changes in this one - HW.
+
+Index: u-boot/drivers/usbtty.c
+===================================================================
+--- u-boot.orig/drivers/usbtty.c       2007-02-08 21:11:27.000000000 +0100
++++ u-boot/drivers/usbtty.c    2007-02-08 21:11:55.000000000 +0100
+@@ -1,6 +1,9 @@
+ /*
+  * (C) Copyright 2003
+  * Gerry Hamel, geh@ti.com, Texas Instruments
++ * 
++ * (C) Copyright 2006
++ * Bryan O'Donoghue, bodonoghue <at> codehermit.ie
+  *
+  * 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
+@@ -22,26 +25,61 @@
+ #ifdef CONFIG_USB_TTY
++#include <asm/io.h>
+ #include <circbuf.h>
+ #include <devices.h>
+ #include "usbtty.h"
++#include "usb_cdc_acm.h"
++#include "usbdescriptors.h"
++#include <config.h>           /* If defined, override Linux identifiers with
++                               * vendor specific ones */
+ #if 0
+-#define TTYDBG(fmt,args...) serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args)
++//+++ debug print into memory buffer,like kernel log
++static        char* log_buf = 0x10e00000; // somewhere in RAM
++static        char  log_str[512];
++#define TTYDBG(fmt,args...)\
++      sprintf(log_str,"\n[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args);\
++      memcpy(log_buf, log_str, strlen(log_str));\
++      log_buf+=strlen(log_str);\
++      strcpy(log_buf,"\n---------------------------------------------------")\
++//---
+ #else
+ #define TTYDBG(fmt,args...) do{}while(0)
+ #endif
+ #if 0
+-#define TTYERR(fmt,args...) serial_printf("ERROR![%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args)
++#define TTYDBG(fmt,args...)\
++      serial_printf("[%s] %s %d: "fmt"\n", __FILE__,__FUNCTION__,__LINE__,##args)
++#endif
++
++#if 0
++#define TTYERR(fmt,args...)\
++      serial_printf("ERROR![%s] %s %d: "fmt"\n", __FILE__,__FUNCTION__,\
++      __LINE__,##args)
+ #else
+ #define TTYERR(fmt,args...) do{}while(0)
+ #endif
+ /*
++ * Defines
++ */
++#define NUM_CONFIGS    1
++#define MAX_INTERFACES 2
++#define NUM_ENDPOINTS  3
++#define ACM_TX_ENDPOINT 3
++#define ACM_RX_ENDPOINT 2
++#define GSERIAL_TX_ENDPOINT 2
++#define GSERIAL_RX_ENDPOINT 1
++#define NUM_ACM_INTERFACES 2
++#define NUM_GSERIAL_INTERFACES 1
++#define CONFIG_USBD_DATA_INTERFACE_STR "Bulk Data Interface"
++#define CONFIG_USBD_CTRL_INTERFACE_STR "Control Interface"
++
++/*
+  * Buffers to hold input and output data
+  */
+-#define USBTTY_BUFFER_SIZE 256
++#define USBTTY_BUFFER_SIZE 2048
+ static circbuf_t usbtty_input;
+ static circbuf_t usbtty_output;
+@@ -50,157 +88,336 @@
+  * Instance variables
+  */
+ static device_t usbttydev;
+-static struct usb_device_instance      device_instance[1];
+-static struct usb_bus_instance                 bus_instance[1];
++static struct usb_device_instance device_instance[1];
++static struct usb_bus_instance bus_instance[1];
+ static struct usb_configuration_instance config_instance[NUM_CONFIGS];
+-static struct usb_interface_instance   interface_instance[NUM_INTERFACES];
+-static struct usb_alternate_instance   alternate_instance[NUM_INTERFACES];
+-static struct usb_endpoint_instance    endpoint_instance[NUM_ENDPOINTS+1]; /* one extra for control endpoint */
+-
+-/*
+- * Static allocation of urbs
+- */
+-#define RECV_ENDPOINT 1
+-#define TX_ENDPOINT 2
++static struct usb_interface_instance interface_instance[MAX_INTERFACES];
++static struct usb_alternate_instance alternate_instance[MAX_INTERFACES];
++/* one extra for control endpoint */
++static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1];
+ /*
+  * Global flag
+  */
+ int usbtty_configured_flag = 0;
+-
+ /*
+  * Serial number
+  */
+ static char serial_number[16];
++
+ /*
+- * Descriptors
++ * Descriptors, Strings, Local variables.
+  */
++
++/* defined and used by usbdcore_ep0.c */
++extern struct usb_string_descriptor **usb_strings;
++
++/* Indicies, References */
++static unsigned short rx_endpoint = 0;
++static unsigned short tx_endpoint = 0;
++static unsigned short interface_count = 0;
++static struct usb_string_descriptor *usbtty_string_table[STR_COUNT];
++
++/* USB Descriptor Strings */
+ static u8 wstrLang[4] = {4,USB_DT_STRING,0x9,0x4};
+ static u8 wstrManufacturer[2 + 2*(sizeof(CONFIG_USBD_MANUFACTURER)-1)];
+ static u8 wstrProduct[2 + 2*(sizeof(CONFIG_USBD_PRODUCT_NAME)-1)];
+ static u8 wstrSerial[2 + 2*(sizeof(serial_number) - 1)];
+ static u8 wstrConfiguration[2 + 2*(sizeof(CONFIG_USBD_CONFIGURATION_STR)-1)];
+-static u8 wstrInterface[2 + 2*(sizeof(CONFIG_USBD_INTERFACE_STR)-1)];
+-
+-static struct usb_string_descriptor *usbtty_string_table[] = {
+-  (struct usb_string_descriptor*)wstrLang,
+-  (struct usb_string_descriptor*)wstrManufacturer,
+-  (struct usb_string_descriptor*)wstrProduct,
+-  (struct usb_string_descriptor*)wstrSerial,
+-  (struct usb_string_descriptor*)wstrConfiguration,
+-  (struct usb_string_descriptor*)wstrInterface
+-};
+-extern struct usb_string_descriptor **usb_strings; /* defined and used by omap1510_ep0.c */
++static u8 wstrDataInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)];
++static u8 wstrCtrlInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)];
++/* Standard USB Data Structures */
++static struct usb_interface_descriptor interface_descriptors[MAX_INTERFACES];
++static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS];
++static struct usb_configuration_descriptor    *configuration_descriptor = 0;
+ static struct usb_device_descriptor device_descriptor = {
+-  bLength:          sizeof(struct usb_device_descriptor),
+-  bDescriptorType:    USB_DT_DEVICE,
+-  bcdUSB:           USB_BCD_VERSION,
+-  bDeviceClass:             USBTTY_DEVICE_CLASS,
+-  bDeviceSubClass:    USBTTY_DEVICE_SUBCLASS,
+-  bDeviceProtocol:    USBTTY_DEVICE_PROTOCOL,
+-  bMaxPacketSize0:    EP0_MAX_PACKET_SIZE,
+-  idVendor:         CONFIG_USBD_VENDORID,
+-  idProduct:        CONFIG_USBD_PRODUCTID,
+-  bcdDevice:        USBTTY_BCD_DEVICE,
+-  iManufacturer:      STR_MANUFACTURER,
+-  iProduct:         STR_PRODUCT,
+-  iSerialNumber:      STR_SERIAL,
+-  bNumConfigurations: NUM_CONFIGS
+-  };
+-static struct usb_configuration_descriptor config_descriptors[NUM_CONFIGS] = {
+-  {
+-    bLength:           sizeof(struct usb_configuration_descriptor),
+-    bDescriptorType:   USB_DT_CONFIG,
+-    wTotalLength:      (sizeof(struct usb_configuration_descriptor)*NUM_CONFIGS) +
+-                       (sizeof(struct usb_interface_descriptor)*NUM_INTERFACES) +
+-                       (sizeof(struct usb_endpoint_descriptor)*NUM_ENDPOINTS),
+-    bNumInterfaces:    NUM_INTERFACES,
+-    bConfigurationValue: 1,
+-    iConfiguration:    STR_CONFIG,
+-    bmAttributes:      BMATTRIBUTE_SELF_POWERED | BMATTRIBUTE_RESERVED,
+-    bMaxPower:                 USBTTY_MAXPOWER
+-  },
+-};
+-static struct usb_interface_descriptor interface_descriptors[NUM_INTERFACES] = {
+-  {
+-    bLength:           sizeof(struct usb_interface_descriptor),
+-    bDescriptorType:   USB_DT_INTERFACE,
+-    bInterfaceNumber:  0,
+-    bAlternateSetting:         0,
+-    bNumEndpoints:     NUM_ENDPOINTS,
+-    bInterfaceClass:   USBTTY_INTERFACE_CLASS,
+-    bInterfaceSubClass:        USBTTY_INTERFACE_SUBCLASS,
+-    bInterfaceProtocol:        USBTTY_INTERFACE_PROTOCOL,
+-    iInterface:                STR_INTERFACE
+-  },
++      .bLength = sizeof(struct usb_device_descriptor),
++      .bDescriptorType =      USB_DT_DEVICE,
++      .bcdUSB =               cpu_to_le16(USB_BCD_VERSION),
++      .bDeviceSubClass =      0x00,
++      .bDeviceProtocol =      0x00,
++      .bMaxPacketSize0 =      EP0_MAX_PACKET_SIZE,
++      .idVendor =             cpu_to_le16(CONFIG_USBD_VENDORID),
++      .bcdDevice =            cpu_to_le16(USBTTY_BCD_DEVICE),
++      .iManufacturer =        STR_MANUFACTURER,
++      .iProduct =             STR_PRODUCT,
++      .iSerialNumber =        STR_SERIAL,
++      .bNumConfigurations =   NUM_CONFIGS
+ };
+-static struct usb_endpoint_descriptor ep_descriptors[NUM_ENDPOINTS] = {
+-  {
+-    bLength:           sizeof(struct usb_endpoint_descriptor),
+-    bDescriptorType:   USB_DT_ENDPOINT,
+-    bEndpointAddress:  CONFIG_USBD_SERIAL_OUT_ENDPOINT | USB_DIR_OUT,
+-    bmAttributes:      USB_ENDPOINT_XFER_BULK,
+-    wMaxPacketSize:    CONFIG_USBD_SERIAL_OUT_PKTSIZE,
+-    bInterval:                 0
+-  },
+-  {
+-    bLength:           sizeof(struct usb_endpoint_descriptor),
+-    bDescriptorType:   USB_DT_ENDPOINT,
+-    bEndpointAddress:  CONFIG_USBD_SERIAL_IN_ENDPOINT | USB_DIR_IN,
+-    bmAttributes:      USB_ENDPOINT_XFER_BULK,
+-    wMaxPacketSize:    CONFIG_USBD_SERIAL_IN_PKTSIZE,
+-    bInterval:                 0
+-  },
+-  {
+-    bLength:           sizeof(struct usb_endpoint_descriptor),
+-    bDescriptorType:   USB_DT_ENDPOINT,
+-    bEndpointAddress:  CONFIG_USBD_SERIAL_INT_ENDPOINT | USB_DIR_IN,
+-    bmAttributes:      USB_ENDPOINT_XFER_INT,
+-    wMaxPacketSize:    CONFIG_USBD_SERIAL_INT_PKTSIZE,
+-    bInterval:                 0
+-  },
+-};
+-static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS] = {
+-  &(ep_descriptors[0]),
+-  &(ep_descriptors[1]),
+-  &(ep_descriptors[2]),
++
++
++/*
++ * Static CDC ACM specific descriptors
++ */
++
++struct acm_config_desc {
++      struct usb_configuration_descriptor configuration_desc;
++      
++      /* Master Interface */
++      struct usb_interface_descriptor interface_desc;
++      
++      struct usb_class_header_function_descriptor usb_class_header;
++      struct usb_class_call_management_descriptor usb_class_call_mgt;
++      struct usb_class_abstract_control_descriptor usb_class_acm;
++      struct usb_class_union_function_descriptor usb_class_union;
++      struct usb_endpoint_descriptor notification_endpoint;
++
++      /* Slave Interface */
++      struct usb_interface_descriptor data_class_interface;
++      struct usb_endpoint_descriptor 
++              data_endpoints[NUM_ENDPOINTS-1] __attribute__((packed));
++} __attribute__((packed));
++
++static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = {
++      {
++              .configuration_desc ={
++                      .bLength = 
++                              sizeof(struct usb_configuration_descriptor),
++                      .bDescriptorType = USB_DT_CONFIG,
++                      .wTotalLength =  
++                              cpu_to_le16(sizeof(struct acm_config_desc)),
++                      .bNumInterfaces = NUM_ACM_INTERFACES,
++                      .bConfigurationValue = 1,
++                      .iConfiguration = STR_CONFIG,
++                      .bmAttributes = 
++                              BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
++                      .bMaxPower = USBTTY_MAXPOWER
++              },
++              /* Interface 1 */
++              .interface_desc = {
++                      .bLength  = sizeof(struct usb_interface_descriptor),
++                      .bDescriptorType = USB_DT_INTERFACE,
++                      .bInterfaceNumber = 0,
++                      .bAlternateSetting = 0,
++                      .bNumEndpoints = 0x01,
++                      .bInterfaceClass = 
++                              COMMUNICATIONS_INTERFACE_CLASS_CONTROL,
++                      .bInterfaceSubClass = COMMUNICATIONS_ACM_SUBCLASS,
++                      .bInterfaceProtocol = COMMUNICATIONS_V25TER_PROTOCOL,
++                      .iInterface = STR_CTRL_INTERFACE,
++              },
++              .usb_class_header = {
++                      .bFunctionLength        = 
++                              sizeof(struct usb_class_header_function_descriptor),
++                      .bDescriptorType        = CS_INTERFACE, 
++                      .bDescriptorSubtype     = USB_ST_HEADER,
++                      .bcdCDC = cpu_to_le16(110),
++              },
++              .usb_class_call_mgt = {
++                      .bFunctionLength        = 
++                              sizeof(struct usb_class_call_management_descriptor),
++                      .bDescriptorType        = CS_INTERFACE,
++                      .bDescriptorSubtype     = USB_ST_CMF,
++                      .bmCapabilities         = 0x00, 
++                      .bDataInterface         = 0x01, 
++              },
++              .usb_class_acm = {
++                      .bFunctionLength        = 
++                              sizeof(struct usb_class_abstract_control_descriptor),
++                      .bDescriptorType        = CS_INTERFACE,
++                      .bDescriptorSubtype     = USB_ST_ACMF,  
++                      .bmCapabilities         = 0x00, 
++              },
++              .usb_class_union = {
++                      .bFunctionLength        =       
++                              sizeof(struct usb_class_union_function_descriptor),
++                      .bDescriptorType        = CS_INTERFACE,
++                      .bDescriptorSubtype     = USB_ST_UF,
++                      .bMasterInterface       = 0x00, 
++                      .bSlaveInterface0       = 0x01, 
++              },
++              .notification_endpoint = {
++                      .bLength =              
++                              sizeof(struct usb_endpoint_descriptor),
++                      .bDescriptorType        = USB_DT_ENDPOINT,
++                      .bEndpointAddress       = 0x01 | USB_DIR_IN,
++                      .bmAttributes           = USB_ENDPOINT_XFER_INT,
++                      .wMaxPacketSize         
++                              = cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
++                      .bInterval              = 0xFF,
++              },
++
++              /* Interface 2 */
++              .data_class_interface = {
++                      .bLength                = 
++                              sizeof(struct usb_interface_descriptor),
++                      .bDescriptorType        = USB_DT_INTERFACE,
++                      .bInterfaceNumber       = 0x01,
++                      .bAlternateSetting      = 0x00,
++                      .bNumEndpoints          = 0x02,
++                      .bInterfaceClass        = 
++                              COMMUNICATIONS_INTERFACE_CLASS_DATA,
++                      .bInterfaceSubClass     = DATA_INTERFACE_SUBCLASS_NONE,
++                      .bInterfaceProtocol     = DATA_INTERFACE_PROTOCOL_NONE,
++                      .iInterface             = STR_DATA_INTERFACE,
++              },
++              .data_endpoints = {
++                      {
++                              .bLength                = 
++                                      sizeof(struct usb_endpoint_descriptor),
++                              .bDescriptorType        = USB_DT_ENDPOINT,
++                              .bEndpointAddress       = 0x02 | USB_DIR_OUT,
++                              .bmAttributes           = 
++                                      USB_ENDPOINT_XFER_BULK,
++                              .wMaxPacketSize         = 
++                                      cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
++                              .bInterval              = 0xFF,
++                      },
++                      {
++                              .bLength                = 
++                                      sizeof(struct usb_endpoint_descriptor),
++                              .bDescriptorType        = USB_DT_ENDPOINT,
++                              .bEndpointAddress       = 0x03 | USB_DIR_IN,
++                              .bmAttributes           = 
++                                      USB_ENDPOINT_XFER_BULK,
++                              .wMaxPacketSize         = 
++                                      cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
++                              .bInterval              = 0xFF,
++                      },
++              },
++      },
++};    
++
++static struct rs232_emu rs232_desc={
++              .dter           =       115200,
++              .stop_bits      =       0x00,
++              .parity         =       0x00,
++              .data_bits      =       0x08
+ };
+-/* utility function for converting char* to wide string used by USB */
+-static void str2wide (char *str, u16 * wide)
+-{
+-      int i;
+-      for (i = 0; i < strlen (str) && str[i]; i++)
+-              wide[i] = (u16) str[i];
+-}
++/*
++ * Static Generic Serial specific data
++ */
++
++
++struct gserial_config_desc {
++      
++      struct usb_configuration_descriptor configuration_desc;
++      struct usb_interface_descriptor 
++              interface_desc[NUM_GSERIAL_INTERFACES] __attribute__((packed));
++      struct usb_endpoint_descriptor 
++              data_endpoints[NUM_ENDPOINTS] __attribute__((packed));
++
++} __attribute__((packed));
++
++static struct gserial_config_desc 
++gserial_configuration_descriptors[NUM_CONFIGS] ={
++      {
++              .configuration_desc ={
++                      .bLength = sizeof(struct usb_configuration_descriptor),
++                      .bDescriptorType = USB_DT_CONFIG,
++                      .wTotalLength =  
++                              cpu_to_le16(sizeof(struct gserial_config_desc)),
++                      .bNumInterfaces = NUM_GSERIAL_INTERFACES,
++                      .bConfigurationValue = 1,
++                      .iConfiguration = STR_CONFIG,
++                      .bmAttributes = 
++                              BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
++                      .bMaxPower = USBTTY_MAXPOWER
++              },
++              .interface_desc = {
++                      {
++                              .bLength  = 
++                                      sizeof(struct usb_interface_descriptor),
++                              .bDescriptorType = USB_DT_INTERFACE,
++                              .bInterfaceNumber = 0,
++                              .bAlternateSetting = 0,
++                              .bNumEndpoints = NUM_ENDPOINTS,
++                              .bInterfaceClass = 
++                                      COMMUNICATIONS_INTERFACE_CLASS_VENDOR,
++                              .bInterfaceSubClass = 
++                                      COMMUNICATIONS_NO_SUBCLASS,
++                              .bInterfaceProtocol = 
++                                      COMMUNICATIONS_NO_PROTOCOL,
++                              .iInterface = STR_DATA_INTERFACE
++                      },
++              },
++              .data_endpoints  = {
++                      {
++                              .bLength =              
++                                      sizeof(struct usb_endpoint_descriptor),
++                              .bDescriptorType =      USB_DT_ENDPOINT,
++                              .bEndpointAddress =     0x01 | USB_DIR_OUT,
++                              .bmAttributes =         USB_ENDPOINT_XFER_BULK,
++                              .wMaxPacketSize =       
++                                      cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE),
++                              .bInterval=             0xFF,
++                      },
++                      {
++                              .bLength =              
++                                      sizeof(struct usb_endpoint_descriptor),
++                              .bDescriptorType =      USB_DT_ENDPOINT,
++                              .bEndpointAddress =     0x02 | USB_DIR_IN,
++                              .bmAttributes =         USB_ENDPOINT_XFER_BULK,
++                              .wMaxPacketSize =       
++                                      cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE),
++                              .bInterval =            0xFF,
++                      },
++                      {
++                              .bLength =              
++                                      sizeof(struct usb_endpoint_descriptor),
++                              .bDescriptorType =      USB_DT_ENDPOINT,
++                              .bEndpointAddress =     0x03 | USB_DIR_IN,
++                              .bmAttributes =         USB_ENDPOINT_XFER_INT,
++                              .wMaxPacketSize =       
++                                      cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
++                              .bInterval =            0xFF,
++                      },
++              },
++      },
++};
+ /*
+- * Prototypes
++ * Static Function Prototypes
+  */
++
+ static void usbtty_init_strings (void);
+ static void usbtty_init_instances (void);
+ static void usbtty_init_endpoints (void);
+-
++static void usbtty_init_terminal_type(short type);
+ static void usbtty_event_handler (struct usb_device_instance *device,
+-                                usb_device_event_t event, int data);
++                              usb_device_event_t event, int data);
++static int usbtty_cdc_setup(struct usb_device_request *request, 
++                              struct urb *urb);
+ static int usbtty_configured (void);
+-
+ static int write_buffer (circbuf_t * buf);
+ static int fill_buffer (circbuf_t * buf);
+ void usbtty_poll (void);
+-static void pretend_interrupts (void);
++/* utility function for converting char* to wide string used by USB */
++static void str2wide (char *str, u16 * wide)
++{
++      int i;
++      for (i = 0; i < strlen (str) && str[i]; i++){
++              #if defined(__LITTLE_ENDIAN)
++                      wide[i] = (u16) str[i];
++              #elif defined(__BIG_ENDIAN)
++                      wide[i] = ((u16)(str[i])<<8);
++              #else
++                      #error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined"
++              #endif
++      }
++}
+ /*
+  * Test whether a character is in the RX buffer
+  */
++
+ int usbtty_tstc (void)
+ {
++      struct usb_endpoint_instance *endpoint =
++              &endpoint_instance[rx_endpoint];
++
++      /* If no input data exists, allow more RX to be accepted */
++      if(usbtty_input.size <= 0){
++              udc_unset_nak(endpoint->endpoint_address&0x03);
++      }
++
+       usbtty_poll ();
+       return (usbtty_input.size > 0);
+ }
+@@ -210,15 +427,21 @@
+  * otherwise. When the function is succesfull, the character read is
+  * written into its argument c.
+  */
++
+ int usbtty_getc (void)
+ {
+       char c;
++      struct usb_endpoint_instance *endpoint =
++              &endpoint_instance[rx_endpoint];
+       while (usbtty_input.size <= 0) {
++              udc_unset_nak(endpoint->endpoint_address&0x03);
+               usbtty_poll ();
+       }
+       buf_pop (&usbtty_input, &c, 1);
++      udc_set_nak(endpoint->endpoint_address&0x03);
++
+       return c;
+ }
+@@ -238,7 +461,6 @@
+       }
+ }
+-
+ /* usbtty_puts() helper function for finding the next '\n' in a string */
+ static int next_nl_pos (const char *s)
+ {
+@@ -252,8 +474,9 @@
+ }
+ /*
+- * Output a string to the usb client port.
++ * Output a string to the usb client port - implementing flow control
+  */
++
+ static void __usbtty_puts (const char *str, int len)
+ {
+       int maxlen = usbtty_output.totalsize;
+@@ -261,22 +484,19 @@
+       /* break str into chunks < buffer size, if needed */
+       while (len > 0) {
+-              space = maxlen - usbtty_output.size;
++              usbtty_poll ();
++              space = maxlen - usbtty_output.size;
+               /* Empty buffer here, if needed, to ensure space... */
+-              if (space <= 0) {
++              if (space) {
+                       write_buffer (&usbtty_output);
+-                      space = maxlen - usbtty_output.size;
+-                      if (space <= 0) {
+-                              space = len;    /* allow old data to be overwritten. */
+-                      }
+-              }
+-
+-              n = MIN (space, MIN (len, maxlen));
+-              buf_push (&usbtty_output, str, n);
++                      
++                      n = MIN (space, MIN (len, maxlen));
++                      buf_push (&usbtty_output, str, n);
+-              str += n;
+-              len -= n;
++                      str += n;
++                      len -= n;                       
++              }
+       }
+ }
+@@ -313,8 +533,10 @@
+ {
+       int rc;
+       char * sn;
++      char * tt;
+       int snlen;
++      /* Get serial number */
+       if (!(sn = getenv("serial#"))) {
+               sn = "000000000000";
+       }
+@@ -327,6 +549,14 @@
+       memcpy (serial_number, sn, snlen);
+       serial_number[snlen] = '\0';
++      /* Decide on which type of UDC device to be.
++       */
++
++      if(!(tt = getenv("usbtty"))) {
++              tt = "generic";
++      }
++      usbtty_init_terminal_type(strcmp(tt,"cdc_acm"));
++      
+       /* prepare buffers... */
+       buf_init (&usbtty_input, USBTTY_BUFFER_SIZE);
+       buf_init (&usbtty_output, USBTTY_BUFFER_SIZE);
+@@ -337,7 +567,7 @@
+       usbtty_init_strings ();
+       usbtty_init_instances ();
+-      udc_startup_events (device_instance);   /* Enable our device, initialize udc pointers */
++      udc_startup_events (device_instance);/* Enable dev, init udc pointers */
+       udc_connect ();         /* Enable pullup for host detection */
+       usbtty_init_endpoints ();
+@@ -362,34 +592,52 @@
+ {
+       struct usb_string_descriptor *string;
++      usbtty_string_table[STR_LANG] = 
++              (struct usb_string_descriptor*)wstrLang;
++
+       string = (struct usb_string_descriptor *) wstrManufacturer;
+-      string->bLength = sizeof (wstrManufacturer);
++      string->bLength = sizeof(wstrManufacturer);
+       string->bDescriptorType = USB_DT_STRING;
+       str2wide (CONFIG_USBD_MANUFACTURER, string->wData);
++      usbtty_string_table[STR_MANUFACTURER]=string;
++
+       string = (struct usb_string_descriptor *) wstrProduct;
+-      string->bLength = sizeof (wstrProduct);
++      string->bLength = sizeof(wstrProduct);
+       string->bDescriptorType = USB_DT_STRING;
+       str2wide (CONFIG_USBD_PRODUCT_NAME, string->wData);
++      usbtty_string_table[STR_PRODUCT]=string;
++
+       string = (struct usb_string_descriptor *) wstrSerial;
+-      string->bLength = 2 + 2*strlen(serial_number);
++      string->bLength = sizeof(serial_number);
+       string->bDescriptorType = USB_DT_STRING;
+       str2wide (serial_number, string->wData);
++      usbtty_string_table[STR_SERIAL]=string;
++
+       string = (struct usb_string_descriptor *) wstrConfiguration;
+-      string->bLength = sizeof (wstrConfiguration);
++      string->bLength = sizeof(wstrConfiguration);
+       string->bDescriptorType = USB_DT_STRING;
+       str2wide (CONFIG_USBD_CONFIGURATION_STR, string->wData);
++      usbtty_string_table[STR_CONFIG]=string;
++
++
++      string = (struct usb_string_descriptor *) wstrDataInterface;
++      string->bLength = sizeof(wstrDataInterface);
++      string->bDescriptorType = USB_DT_STRING;
++      str2wide (CONFIG_USBD_DATA_INTERFACE_STR, string->wData);
++      usbtty_string_table[STR_DATA_INTERFACE]=string;
+-      string = (struct usb_string_descriptor *) wstrInterface;
+-      string->bLength = sizeof (wstrInterface);
++      string = (struct usb_string_descriptor *) wstrCtrlInterface;
++      string->bLength = sizeof(wstrCtrlInterface);
+       string->bDescriptorType = USB_DT_STRING;
+-      str2wide (CONFIG_USBD_INTERFACE_STR, string->wData);
++      str2wide (CONFIG_USBD_CTRL_INTERFACE_STR, string->wData);
++      usbtty_string_table[STR_CTRL_INTERFACE]=string;
+       /* Now, initialize the string table for ep0 handling */
+       usb_strings = usbtty_string_table;
+-}
++}     
+ static void usbtty_init_instances (void)
+ {
+@@ -400,6 +648,7 @@
+       device_instance->device_state = STATE_INIT;
+       device_instance->device_descriptor = &device_descriptor;
+       device_instance->event = usbtty_event_handler;
++      device_instance->cdc_recv_setup = usbtty_cdc_setup;
+       device_instance->bus = bus_instance;
+       device_instance->configurations = NUM_CONFIGS;
+       device_instance->configuration_instance_array = config_instance;
+@@ -415,8 +664,8 @@
+       /* configuration instance */
+       memset (config_instance, 0,
+               sizeof (struct usb_configuration_instance));
+-      config_instance->interfaces = NUM_INTERFACES;
+-      config_instance->configuration_descriptor = config_descriptors;
++      config_instance->interfaces = interface_count;
++      config_instance->configuration_descriptor = configuration_descriptor;
+       config_instance->interface_instance_array = interface_instance;
+       /* interface instance */
+@@ -447,17 +696,22 @@
+                       sizeof (struct usb_endpoint_instance));
+               endpoint_instance[i].endpoint_address =
+-                      ep_descriptors[i - 1].bEndpointAddress;
++                      ep_descriptor_ptrs[i - 1]->bEndpointAddress;
+-              endpoint_instance[i].rcv_packetSize =
+-                      ep_descriptors[i - 1].wMaxPacketSize;
+               endpoint_instance[i].rcv_attributes =
+-                      ep_descriptors[i - 1].bmAttributes;
++                      ep_descriptor_ptrs[i - 1]->bmAttributes;
++
++              endpoint_instance[i].rcv_packetSize =
++                      le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize);
++              
++              endpoint_instance[i].tx_attributes =
++                      ep_descriptor_ptrs[i - 1]->bmAttributes;
+               endpoint_instance[i].tx_packetSize =
+-                      ep_descriptors[i - 1].wMaxPacketSize;
++                      le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize);
++
+               endpoint_instance[i].tx_attributes =
+-                      ep_descriptors[i - 1].bmAttributes;
++                      ep_descriptor_ptrs[i - 1]->bmAttributes;
+               urb_link_init (&endpoint_instance[i].rcv);
+               urb_link_init (&endpoint_instance[i].rdy);
+@@ -480,13 +734,79 @@
+       int i;
+       bus_instance->max_endpoints = NUM_ENDPOINTS + 1;
+-      for (i = 0; i <= NUM_ENDPOINTS; i++) {
++      for (i = 1; i <= NUM_ENDPOINTS; i++) {          
+               udc_setup_ep (device_instance, i, &endpoint_instance[i]);
+       }
+ }
++/* usbtty_init_terminal_type
++ * 
++ * Do some late binding for our device type.
++ */
++static void usbtty_init_terminal_type(short type)
++{
++      switch(type){
++              /* CDC ACM */                   
++              case 0:
++                      /* Assign endpoint descriptors */
++                      ep_descriptor_ptrs[0] = 
++                              &acm_configuration_descriptors[0].notification_endpoint;
++                      ep_descriptor_ptrs[1] = 
++                              &acm_configuration_descriptors[0].data_endpoints[0];
++                      ep_descriptor_ptrs[2] = 
++                              &acm_configuration_descriptors[0].data_endpoints[1];
++
++                      /* Enumerate Device Descriptor */
++                      device_descriptor.bDeviceClass = 
++                              COMMUNICATIONS_DEVICE_CLASS;
++                      device_descriptor.idProduct =
++                              cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM);
++
++                      /* Assign endpoint indices */
++                      tx_endpoint = ACM_TX_ENDPOINT;
++                      rx_endpoint = ACM_RX_ENDPOINT;
++                      
++                      /* Configuration Descriptor */
++                      configuration_descriptor =
++                              (struct usb_configuration_descriptor*)
++                              &acm_configuration_descriptors;
++
++                      /* Interface count */
++                      interface_count = NUM_ACM_INTERFACES;
++              break;
++
++              /* BULK IN/OUT & Default */
++              case 1:
++              default:
++                      /* Assign endpoint descriptors */
++                      ep_descriptor_ptrs[0] = 
++                              &gserial_configuration_descriptors[0].data_endpoints[0];
++                      ep_descriptor_ptrs[1] = 
++                              &gserial_configuration_descriptors[0].data_endpoints[1];
++                      ep_descriptor_ptrs[2] = 
++                              &gserial_configuration_descriptors[0].data_endpoints[2];
++
++                      /* Enumerate Device Descriptor */
++                      device_descriptor.bDeviceClass = 0xFF;
++                      device_descriptor.idProduct =
++                              cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL);
++
++                      /* Assign endpoint indices */
++                      tx_endpoint = GSERIAL_TX_ENDPOINT;
++                      rx_endpoint = GSERIAL_RX_ENDPOINT;
++
++                      /* Configuration Descriptor */
++                      configuration_descriptor = 
++                              (struct usb_configuration_descriptor*)
++                              &gserial_configuration_descriptors;
++
++                      /* Interface count */
++                      interface_count = NUM_GSERIAL_INTERFACES;
++              break;
++      }
++}
+-/*********************************************************************************/
++/******************************************************************************/
+ static struct urb *next_urb (struct usb_device_instance *device,
+                            struct usb_endpoint_instance *endpoint)
+@@ -522,82 +842,179 @@
+ static int write_buffer (circbuf_t * buf)
+ {
+-      if (!usbtty_configured ()) {
+-              return 0;
+-      }
++        if (!usbtty_configured ()) {
++                return 0;
++        }
++
++        if (buf->size) {
++
++                struct usb_endpoint_instance *endpoint =
++                        &endpoint_instance[tx_endpoint];
++                struct urb *current_urb = NULL;
++                char *dest;
++
++                int space_avail;
++                int popnum, popped;
++                int total = 0;
++
++                /* Break buffer into urb sized pieces, and link each to the endpoint */
++                while (buf->size > 0) {
++              TTYDBG ("buf->size= %d",buf->size);
++                        current_urb = next_urb (device_instance, endpoint);
++                        if (!current_urb) {
++                                TTYDBG ("current_urb is NULL, buf->size %d\n",
++                                        buf->size);
++                                return total;
++                        }
++
++                        dest = current_urb->buffer +
++                                current_urb->actual_length;
++
++                        space_avail =
++                                current_urb->buffer_length -
++                                current_urb->actual_length;
++              TTYDBG ("space_avail= %d",space_avail);
++                        popnum = MIN (space_avail, buf->size);
++                        if (popnum == 0)
++                                break;
++
++                        popped = buf_pop (buf, dest, popnum);
++              TTYDBG ("popped= %d, %s",popped, dest);
++                        if (popped == 0)
++                                break;
++                        current_urb->actual_length += popped;
++                        total += popped;
++
++                        /* If endpoint->last == 0, then transfers have not started on this endpoint */
++                        if (endpoint->last == 0) {
++                                udc_endpoint_write (endpoint);
++                        }
++
++                }               /* end while */
++              TTYDBG (" total= %d",total);
++                return total;
++        }                       /* end if tx_urb */
+-      if (buf->size) {
++        return 0;
++}
++// static int write_buffer (circbuf_t * buf)
++// {
++//    if (!usbtty_configured ()) {
++//            return 0;
++//    }
++//    
++//    struct usb_endpoint_instance *endpoint =
++//                    &endpoint_instance[tx_endpoint];
++//    struct urb *current_urb = NULL;
++// 
++//    current_urb = next_urb (device_instance, endpoint);
++//    /* TX data still exists - send it now 
++//     */     
++//    if(endpoint->sent < current_urb->actual_length){
++//            if(udc_endpoint_write (endpoint)){
++//                    /* Write pre-empted by RX */
++//                    return -1;
++//            }
++//    }
++// 
++//    if (buf->size) {
++//            char *dest;
++// 
++//            int space_avail;
++//            int popnum, popped;
++//            int total = 0;
++// 
++//            /* Break buffer into urb sized pieces, 
++//             * and link each to the endpoint 
++//             */
++//            while (buf->size > 0) {
++//                    
++//                    if (!current_urb) {
++//                            TTYERR ("current_urb is NULL, buf->size %d\n",
++//                                    buf->size);
++//                            return total;
++//                    }
++// 
++//                    dest = (char*)current_urb->buffer +
++//                            current_urb->actual_length;
++// 
++//                    space_avail =
++//                            current_urb->buffer_length -
++//                            current_urb->actual_length;
++//                    popnum = MIN (space_avail, buf->size);
++//                    if (popnum == 0)
++//                            break;
++// 
++//                    popped = buf_pop (buf, dest, popnum);
++//                    if (popped == 0)
++//                            break;
++//                    current_urb->actual_length += popped;
++//                    total += popped;
++// 
++//                    /* If endpoint->last == 0, then transfers have 
++//                     * not started on this endpoint 
++//                     */
++//                    if (endpoint->last == 0) {
++//                            if(udc_endpoint_write (endpoint)){
++//                                    /* Write pre-empted by RX */
++//                                    return -1;
++//                            }
++//                    }
++// 
++//            }/* end while */
++//            return total;
++//    }
++// 
++//    return 0;
++// }
+-              struct usb_endpoint_instance *endpoint =
+-                      &endpoint_instance[TX_ENDPOINT];
+-              struct urb *current_urb = NULL;
+-              char *dest;
+-
+-              int space_avail;
+-              int popnum, popped;
+-              int total = 0;
+-
+-              /* Break buffer into urb sized pieces, and link each to the endpoint */
+-              while (buf->size > 0) {
+-                      current_urb = next_urb (device_instance, endpoint);
+-                      if (!current_urb) {
+-                              TTYERR ("current_urb is NULL, buf->size %d\n",
+-                                      buf->size);
+-                              return total;
+-                      }
+-
+-                      dest = current_urb->buffer +
+-                              current_urb->actual_length;
+-
+-                      space_avail =
+-                              current_urb->buffer_length -
+-                              current_urb->actual_length;
+-                      popnum = MIN (space_avail, buf->size);
+-                      if (popnum == 0)
+-                              break;
+-
+-                      popped = buf_pop (buf, dest, popnum);
+-                      if (popped == 0)
+-                              break;
+-                      current_urb->actual_length += popped;
+-                      total += popped;
+-
+-                      /* If endpoint->last == 0, then transfers have not started on this endpoint */
+-                      if (endpoint->last == 0) {
+-                              udc_endpoint_write (endpoint);
+-                      }
+-
+-              }               /* end while */
+-              return total;
+-      }                       /* end if tx_urb */
++static int fill_buffer (circbuf_t * buf)
++{
++        struct usb_endpoint_instance *endpoint =
++                &endpoint_instance[rx_endpoint];
+-      return 0;
+-}
++        if (endpoint->rcv_urb && endpoint->rcv_urb->actual_length) {
++              unsigned int nb = endpoint->rcv_urb->actual_length;
++                char *src = (char *) endpoint->rcv_urb->buffer;
++                buf_push (buf, src, nb);
++                endpoint->rcv_urb->actual_length = 0;
++
++              TTYDBG ("nb= %d",nb);
++                return nb;
++        }
++
++        return 0;
++}
++/*
+ static int fill_buffer (circbuf_t * buf)
+ {
+       struct usb_endpoint_instance *endpoint =
+-              &endpoint_instance[RECV_ENDPOINT];
++              &endpoint_instance[rx_endpoint];
+       if (endpoint->rcv_urb && endpoint->rcv_urb->actual_length) {
+-              unsigned int nb = endpoint->rcv_urb->actual_length;
++              unsigned int nb = 0; 
+               char *src = (char *) endpoint->rcv_urb->buffer;
++              unsigned int rx_avail = buf->totalsize - buf->size;
+-              buf_push (buf, src, nb);
+-              endpoint->rcv_urb->actual_length = 0;
++              if(rx_avail >= endpoint->rcv_urb->actual_length){
++                      nb = endpoint->rcv_urb->actual_length;
++                      buf_push (buf, src, nb);
++                      endpoint->rcv_urb->actual_length = 0;
++                      
++              }
+               return nb;
+       }
+-
+       return 0;
+ }
+-
++*/
+ static int usbtty_configured (void)
+ {
+       return usbtty_configured_flag;
+ }
+-/*********************************************************************************/
++/******************************************************************************/
+ static void usbtty_event_handler (struct usb_device_instance *device,
+                                 usb_device_event_t event, int data)
+@@ -619,8 +1036,34 @@
+       }
+ }
+-/*********************************************************************************/
++/******************************************************************************/
++int usbtty_cdc_setup(struct usb_device_request *request, struct urb *urb)
++{
++      switch (request->bRequest){
++
++              case ACM_SET_CONTROL_LINE_STATE:        /* Implies DTE ready */
++                      break;
++              case ACM_SEND_ENCAPSULATED_COMMAND :    /* Required */
++                      break;
++              case ACM_SET_LINE_ENCODING :            /* DTE stop/parity bits
++                                                       * per character */             
++                      break;
++              case ACM_GET_ENCAPSULATED_RESPONSE :    /* request response */
++                      break;
++              case ACM_GET_LINE_ENCODING :            /* request DTE rate,
++                                                       * stop/parity bits */
++                      memcpy (urb->buffer , &rs232_desc, sizeof(rs232_desc));
++                      urb->actual_length = sizeof(rs232_desc);
++
++                      break;
++              default:
++                      return 1;
++      }
++      return 0;
++}
++
++/******************************************************************************/
+ /*
+  * Since interrupt handling has not yet been implemented, we use this function
+@@ -630,36 +1073,29 @@
+ void usbtty_poll (void)
+ {
+       /* New interrupts? */
+-      pretend_interrupts ();
++      udc_irq();
+-      /* Write any output data to host buffer (do this before checking interrupts to avoid missing one) */
++      /* Write any output data to host buffer 
++       * (do this before checking interrupts to avoid missing one) 
++       */
+       if (usbtty_configured ()) {
+               write_buffer (&usbtty_output);
+       }
+       /* New interrupts? */
+-      pretend_interrupts ();
+-
+-      /* Check for new data from host.. (do this after checking interrupts to get latest data) */
++      udc_irq();
++      
++      /* Check for new data from host.. 
++       * (do this after checking interrupts to get latest data) 
++       */
+       if (usbtty_configured ()) {
+               fill_buffer (&usbtty_input);
+       }
+       /* New interrupts? */
+-      pretend_interrupts ();
+-}
++      udc_irq();
+-static void pretend_interrupts (void)
+-{
+-      /* Loop while we have interrupts.
+-       * If we don't do this, the input chain
+-       * polling delay is likely to miss
+-       * host requests.
+-       */
+-      while (inw (UDC_IRQ_SRC) & ~UDC_SOF_Flg) {
+-              /* Handle any new IRQs */
+-              omap1510_udc_irq ();
+-              omap1510_udc_noniso_irq ();
+-      }
+ }
++
++
+ #endif
+Index: u-boot/drivers/usbtty.h
+===================================================================
+--- u-boot.orig/drivers/usbtty.h       2007-02-08 21:11:27.000000000 +0100
++++ u-boot/drivers/usbtty.h    2007-02-08 21:11:55.000000000 +0100
+@@ -2,6 +2,9 @@
+  * (C) Copyright 2003
+  * Gerry Hamel, geh@ti.com, Texas Instruments
+  *
++ * (C) Copyright 2006
++ * Bryan O'Donoghue, bodonoghue <at> codehermit.ie, CodeHermit
++ *
+  * 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
+@@ -21,44 +24,49 @@
+ #ifndef __USB_TTY_H__
+ #define __USB_TTY_H__
+-
+ #include "usbdcore.h"
++#if defined(CONFIG_PPC)
++#include "usbdcore_mpc8xx.h"
++#elif defined(CONFIG_OMAP1510)
+ #include "usbdcore_omap1510.h"
++#endif
++#include <config.h>
++#include <version.h>
+-#define NUM_CONFIGS    1
+-#define NUM_INTERFACES 1
+-#define NUM_ENDPOINTS  3
++/* If no VendorID/ProductID is defined in config.h, pretend to be Linux 
++ * DO NOT Reuse this Vendor/Product setup with protocol incompatible devices */
+-#define EP0_MAX_PACKET_SIZE 64
++#ifndef CONFIG_USBD_VENDORID
++#define CONFIG_USBD_VENDORID 0x0525   /* Linux/NetChip */
++#define CONFIG_USBD_PRODUCTID_GSERIAL 0xa4a6  /* gserial */
++#define CONFIG_USBD_PRODUCTID_CDCACM  0xa4a7  /* CDC ACM */
++#define CONFIG_USBD_MANUFACTURER "Das U-Boot"
++#define CONFIG_USBD_PRODUCT_NAME U_BOOT_VERSION
++#endif /* CONFIG_USBD_VENDORID */
+ #define CONFIG_USBD_CONFIGURATION_STR "TTY via USB"
+-#define CONFIG_USBD_INTERFACE_STR     "Simple Serial Data Interface - Bulk Mode"
+-
+-
+-#define CONFIG_USBD_SERIAL_OUT_ENDPOINT 2
+-#define CONFIG_USBD_SERIAL_OUT_PKTSIZE        64
+-#define CONFIG_USBD_SERIAL_IN_ENDPOINT        1
+-#define CONFIG_USBD_SERIAL_IN_PKTSIZE 64
+-#define CONFIG_USBD_SERIAL_INT_ENDPOINT 5
+-#define CONFIG_USBD_SERIAL_INT_PKTSIZE        16
++#define CONFIG_USBD_SERIAL_OUT_ENDPOINT UDC_OUT_ENDPOINT 
++#define CONFIG_USBD_SERIAL_OUT_PKTSIZE        UDC_OUT_PACKET_SIZE
++#define CONFIG_USBD_SERIAL_IN_ENDPOINT        UDC_IN_ENDPOINT
++#define CONFIG_USBD_SERIAL_IN_PKTSIZE UDC_IN_PACKET_SIZE
++#define CONFIG_USBD_SERIAL_INT_ENDPOINT UDC_INT_ENDPOINT
++#define CONFIG_USBD_SERIAL_INT_PKTSIZE        UDC_INT_PACKET_SIZE
++#define CONFIG_USBD_SERIAL_BULK_PKTSIZE       UDC_BULK_PACKET_SIZE
+ #define USBTTY_DEVICE_CLASS   COMMUNICATIONS_DEVICE_CLASS
+-#define USBTTY_DEVICE_SUBCLASS        COMMUNICATIONS_NO_SUBCLASS
+-#define USBTTY_DEVICE_PROTOCOL        COMMUNICATIONS_NO_PROTOCOL
+-#define USBTTY_INTERFACE_CLASS           0xFF /* Vendor Specific */
+-#define USBTTY_INTERFACE_SUBCLASS  0x02
+-#define USBTTY_INTERFACE_PROTOCOL  0x01
+-
+-#define USBTTY_BCD_DEVICE 0x0
+-#define USBTTY_MAXPOWER         0x0
+-
+-#define STR_MANUFACTURER 1
+-#define STR_PRODUCT    2
+-#define STR_SERIAL     3
+-#define STR_CONFIG     4
+-#define STR_INTERFACE  5
++#define USBTTY_BCD_DEVICE     0x00
++#define USBTTY_MAXPOWER       0x00
++
++#define STR_LANG              0x00
++#define STR_MANUFACTURER      0x01
++#define STR_PRODUCT           0x02
++#define STR_SERIAL            0x03
++#define STR_CONFIG            0x04
++#define STR_DATA_INTERFACE    0x05
++#define STR_CTRL_INTERFACE    0x06
++#define STR_COUNT             0x07
+ #endif
+Index: u-boot/drivers/usbdcore_omap1510.c
+===================================================================
+--- u-boot.orig/drivers/usbdcore_omap1510.c    2007-02-08 21:11:27.000000000 +0100
++++ u-boot/drivers/usbdcore_omap1510.c 2007-02-08 21:11:55.000000000 +0100
+@@ -960,7 +960,7 @@
+ /* Handle general USB interrupts and dispatch according to type.
+  * This function implements TRM Figure 14-13.
+  */
+-void omap1510_udc_irq (void)
++static void omap1510_udc_irq (void)
+ {
+       u16 irq_src = inw (UDC_IRQ_SRC);
+       int valid_irq = 0;
+@@ -1000,7 +1000,7 @@
+ }
+ /* This function implements TRM Figure 14-26. */
+-void omap1510_udc_noniso_irq (void)
++static void omap1510_udc_noniso_irq (void)
+ {
+       unsigned short epnum;
+       unsigned short irq_src = inw (UDC_IRQ_SRC);
+@@ -1054,6 +1054,20 @@
+                              irq_src);
+ }
++void udc_irq(void)
++{
++      /* Loop while we have interrupts.
++       * If we don't do this, the input chain
++       * polling delay is likely to miss
++       * host requests.
++       */
++      while (inw (UDC_IRQ_SRC) & ~UDC_SOF_Flg) {
++              /* Handle any new IRQs */
++              omap1510_udc_irq ();
++              omap1510_udc_noniso_irq ();
++      }
++}
++
+ /*
+ -------------------------------------------------------------------------------
+ */
+Index: u-boot/include/usb_cdc_acm.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ u-boot/include/usb_cdc_acm.h       2007-02-08 21:11:55.000000000 +0100
+@@ -0,0 +1,43 @@
++/*
++ * (C) Copyright 2006
++ * Bryan O'Donoghue, deckard <at> codehermit.ie, CodeHermit
++ *
++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++/* ACM Control Requests */
++#define ACM_SEND_ENCAPSULATED_COMMAND 0x00
++#define ACM_GET_ENCAPSULATED_RESPONSE 0x01
++#define ACM_SET_COMM_FEATURE          0x02
++#define ACM_GET_COMM_FEATRUE          0x03
++#define ACM_CLEAR_COMM_FEATURE                0x04
++#define ACM_SET_LINE_ENCODING         0x20
++#define ACM_GET_LINE_ENCODING         0x21
++#define ACM_SET_CONTROL_LINE_STATE    0x22
++#define ACM_SEND_BREAK                        0x23
++
++/* ACM Notification Codes */
++#define ACM_NETWORK_CONNECTION                0x00
++#define ACM_RESPONSE_AVAILABLE                0x01
++#define ACM_SERIAL_STATE              0x20
++
++/* Format of response expected by a ACM_GET_LINE_ENCODING request */ 
++struct rs232_emu{
++              unsigned long dter;
++              unsigned char stop_bits;
++              unsigned char parity;
++              unsigned char data_bits;
++}__attribute__((packed));
+Index: u-boot/include/usbdcore_omap1510.h
+===================================================================
+--- u-boot.orig/include/usbdcore_omap1510.h    2007-02-08 21:11:27.000000000 +0100
++++ u-boot/include/usbdcore_omap1510.h 2007-02-08 21:11:55.000000000 +0100
+@@ -161,13 +161,23 @@
+ #define UDC_VBUS_CTRL     (1 << 19)
+ #define UDC_VBUS_MODE     (1 << 18)
+-
+-void omap1510_udc_irq(void);
+-void omap1510_udc_noniso_irq(void);
+-
++/* OMAP Endpoint parameters */
++#define EP0_MAX_PACKET_SIZE 64
++#define UDC_OUT_ENDPOINT 2
++#define UDC_OUT_PACKET_SIZE 64
++#define UDC_IN_ENDPOINT               1
++#define UDC_IN_PACKET_SIZE 64
++#define UDC_INT_ENDPOINT 5
++#define UDC_INT_PACKET_SIZE   16
++#define UDC_BULK_PACKET_SIZE  16
++
++void udc_irq (void);
++/* Flow control */
++void udc_set_nak(int epid);
++void udc_unset_nak (int epid);
+ /* Higher level functions for abstracting away from specific device */
+-void udc_endpoint_write(struct usb_endpoint_instance *endpoint);
++int udc_endpoint_write(struct usb_endpoint_instance *endpoint);
+ int  udc_init (void);
+Index: u-boot/include/usbdescriptors.h
+===================================================================
+--- u-boot.orig/include/usbdescriptors.h       2007-02-08 21:11:27.000000000 +0100
++++ u-boot/include/usbdescriptors.h    2007-02-08 21:11:55.000000000 +0100
+@@ -92,15 +92,17 @@
+ #define COMMUNICATIONS_DEVICE_CLASS   0x02
+ /* c.f. CDC 4.2 Table 15 */
+-#define COMMUNICATIONS_INTERFACE_CLASS        0x02
++#define COMMUNICATIONS_INTERFACE_CLASS_CONTROL        0x02
++#define COMMUNICATIONS_INTERFACE_CLASS_DATA   0x0A
++#define COMMUNICATIONS_INTERFACE_CLASS_VENDOR 0x0FF
+ /* c.f. CDC 4.3 Table 16 */
+-#define COMMUNICATIONS_NO_SUBCLASS    0x00
++#define COMMUNICATIONS_NO_SUBCLASS            0x00
+ #define COMMUNICATIONS_DLCM_SUBCLASS  0x01
+-#define COMMUNICATIONS_ACM_SUBCLASS   0x02
+-#define COMMUNICATIONS_TCM_SUBCLASS   0x03
++#define COMMUNICATIONS_ACM_SUBCLASS           0x02
++#define COMMUNICATIONS_TCM_SUBCLASS           0x03
+ #define COMMUNICATIONS_MCCM_SUBCLASS  0x04
+-#define COMMUNICATIONS_CCM_SUBCLASS   0x05
++#define COMMUNICATIONS_CCM_SUBCLASS           0x05
+ #define COMMUNICATIONS_ENCM_SUBCLASS  0x06
+ #define COMMUNICATIONS_ANCM_SUBCLASS  0x07
+@@ -110,15 +112,22 @@
+ #define COMMUNICATIONS_MDLM_SUBCLASS  0x0a
+ #define COMMUNICATIONS_OBEX_SUBCLASS  0x0b
+-/* c.f. CDC 4.6 Table 18 */
++/* c.f. CDC 4.4 Table 17 */
++#define COMMUNICATIONS_NO_PROTOCOL            0x00
++#define COMMUNICATIONS_V25TER_PROTOCOL        0x01    /*Common AT Hayes compatible*/
++
++/* c.f. CDC 4.5 Table 18 */
+ #define DATA_INTERFACE_CLASS          0x0a
++/* c.f. CDC 4.6 No Table */
++#define DATA_INTERFACE_SUBCLASS_NONE  0x00    /* No subclass pertinent */
++
+ /* c.f. CDC 4.7 Table 19 */
+-#define COMMUNICATIONS_NO_PROTOCOL    0x00
++#define DATA_INTERFACE_PROTOCOL_NONE  0x00    /* No class protcol required */
+ /* c.f. CDC 5.2.3 Table 24 */
+-#define CS_INTERFACE                  0x24
++#define CS_INTERFACE          0x24
+ #define CS_ENDPOINT                   0x25
+ /*
+@@ -128,7 +137,7 @@
+  * c.f. WMCD 5.3 Table 5.3
+  */
+-#define USB_ST_HEADER                 0x00
++#define USB_ST_HEADER         0x00
+ #define USB_ST_CMF                    0x01
+ #define USB_ST_ACMF                   0x02
+ #define USB_ST_DLMF                   0x03
+@@ -137,18 +146,18 @@
+ #define USB_ST_UF                     0x06
+ #define USB_ST_CSF                    0x07
+ #define USB_ST_TOMF                   0x08
+-#define USB_ST_USBTF                  0x09
++#define USB_ST_USBTF          0x09
+ #define USB_ST_NCT                    0x0a
+ #define USB_ST_PUF                    0x0b
+ #define USB_ST_EUF                    0x0c
+ #define USB_ST_MCMF                   0x0d
+ #define USB_ST_CCMF                   0x0e
+ #define USB_ST_ENF                    0x0f
+-#define USB_ST_ATMNF                  0x10
++#define USB_ST_ATMNF          0x10
+ #define USB_ST_WHCM                   0x11
+ #define USB_ST_MDLM                   0x12
+-#define USB_ST_MDLMD                  0x13
++#define USB_ST_MDLMD          0x13
+ #define USB_ST_DMM                    0x14
+ #define USB_ST_OBEX                   0x15
+ #define USB_ST_CS                     0x16
+@@ -312,7 +321,8 @@
+       u8 bDescriptorType;
+       u8 bDescriptorSubtype;  /* 0x06 */
+       u8 bMasterInterface;
+-      u8 bSlaveInterface0[0];
++      //u8 bSlaveInterface0[0];
++      u8 bSlaveInterface0;
+ } __attribute__ ((packed));
+ struct usb_class_country_selection_descriptor {
+Index: u-boot/include/usbdcore.h
+===================================================================
+--- u-boot.orig/include/usbdcore.h     2007-02-08 21:11:27.000000000 +0100
++++ u-boot/include/usbdcore.h  2007-02-08 21:11:55.000000000 +0100
+@@ -576,6 +576,9 @@
+       void (*event) (struct usb_device_instance *device, usb_device_event_t event, int data);
++      /* Do cdc device specific control requests */
++      int (*cdc_recv_setup)(struct usb_device_request *request, struct urb *urb);
++
+       /* bus interface */
+       struct usb_bus_instance *bus;   /* which bus interface driver */
+Index: u-boot/drivers/usbdcore_ep0.c
+===================================================================
+--- u-boot.orig/drivers/usbdcore_ep0.c 2007-02-08 21:12:05.000000000 +0100
++++ u-boot/drivers/usbdcore_ep0.c      2007-02-08 21:12:08.000000000 +0100
+@@ -223,7 +223,6 @@
+       case USB_DESCRIPTOR_TYPE_CONFIGURATION:
+               {
+-                      int bNumInterface;
+                       struct usb_configuration_descriptor
+                               *configuration_descriptor;
+                       struct usb_device_descriptor *device_descriptor;
+@@ -256,105 +255,6 @@
+                                            usb_configuration_descriptor),
+                                    max);
+-
+-                      /* iterate across interfaces for specified configuration */
+-                      dbg_ep0 (0, "bNumInterfaces: %d",
+-                               configuration_descriptor->bNumInterfaces);
+-                      for (bNumInterface = 0;
+-                           bNumInterface <
+-                           configuration_descriptor->bNumInterfaces;
+-                           bNumInterface++) {
+-
+-                              int bAlternateSetting;
+-                              struct usb_interface_instance
+-                                      *interface_instance;
+-
+-                              dbg_ep0 (3, "[%d] bNumInterfaces: %d",
+-                                       bNumInterface,
+-                                       configuration_descriptor->bNumInterfaces);
+-
+-                              if (! (interface_instance = usbd_device_interface_instance (device,
+-                                                                   port, index, bNumInterface)))
+-                              {
+-                                      dbg_ep0 (3, "[%d] interface_instance NULL",
+-                                               bNumInterface);
+-                                      return -1;
+-                              }
+-                              /* iterate across interface alternates */
+-                              for (bAlternateSetting = 0;
+-                                   bAlternateSetting < interface_instance->alternates;
+-                                   bAlternateSetting++) {
+-                                      /*int class; */
+-                                      int bNumEndpoint;
+-                                      struct usb_interface_descriptor *interface_descriptor;
+-
+-                                      struct usb_alternate_instance *alternate_instance;
+-
+-                                      dbg_ep0 (3, "[%d:%d] alternates: %d",
+-                                               bNumInterface,
+-                                               bAlternateSetting,
+-                                               interface_instance->alternates);
+-
+-                                      if (! (alternate_instance = usbd_device_alternate_instance (device, port, index, bNumInterface, bAlternateSetting))) {
+-                                              dbg_ep0 (3, "[%d] alternate_instance NULL",
+-                                                       bNumInterface);
+-                                              return -1;
+-                                      }
+-                                      /* copy descriptor for this interface */
+-                                      copy_config (urb, alternate_instance->interface_descriptor,
+-                                                   sizeof (struct usb_interface_descriptor),
+-                                                   max);
+-
+-                                      /*dbg_ep0(3, "[%d:%d] classes: %d endpoints: %d", bNumInterface, bAlternateSetting, */
+-                                      /*        alternate_instance->classes, alternate_instance->endpoints); */
+-
+-                                      /* iterate across classes for this alternate interface */
+-#if 0
+-                                      for (class = 0;
+-                                           class < alternate_instance->classes;
+-                                           class++) {
+-                                              struct usb_class_descriptor *class_descriptor;
+-                                              /*dbg_ep0(3, "[%d:%d:%d] classes: %d", bNumInterface, bAlternateSetting, */
+-                                              /*        class, alternate_instance->classes); */
+-                                              if (!(class_descriptor = usbd_device_class_descriptor_index (device, port, index, bNumInterface, bAlternateSetting, class))) {
+-                                                      dbg_ep0 (3, "[%d] class NULL",
+-                                                               class);
+-                                                      return -1;
+-                                              }
+-                                              /* copy descriptor for this class */
+-                                              copy_config (urb, class_descriptor,
+-                                                      sizeof (struct usb_class_descriptor),
+-                                                      max);
+-                                      }
+-#endif
+-
+-                                      /* iterate across endpoints for this alternate interface */
+-                                      interface_descriptor = alternate_instance->interface_descriptor;
+-                                      for (bNumEndpoint = 0;
+-                                           bNumEndpoint < alternate_instance->endpoints;
+-                                           bNumEndpoint++) {
+-                                              struct usb_endpoint_descriptor *endpoint_descriptor;
+-                                              dbg_ep0 (3, "[%d:%d:%d] endpoint: %d",
+-                                                       bNumInterface,
+-                                                       bAlternateSetting,
+-                                                       bNumEndpoint,
+-                                                       interface_descriptor->
+-                                                       bNumEndpoints);
+-                                              if (!(endpoint_descriptor = usbd_device_endpoint_descriptor_index (device, port, index, bNumInterface, bAlternateSetting, bNumEndpoint))) {
+-                                                      dbg_ep0 (3, "[%d] endpoint NULL",
+-                                                               bNumEndpoint);
+-                                                      return -1;
+-                                              }
+-                                              /* copy descriptor for this endpoint */
+-                                              copy_config (urb, endpoint_descriptor,
+-                                                           sizeof (struct usb_endpoint_descriptor),
+-                                                           max);
+-                                      }
+-                              }
+-                      }
+-                      dbg_ep0 (3, "lengths: %d %d",
+-                               le16_to_cpu (configuration_descriptor->wTotalLength),
+-                               urb->actual_length);
+               }
+               break;
+@@ -363,6 +263,7 @@
+                       struct usb_string_descriptor *string_descriptor;
+                       if (!(string_descriptor = usbd_get_string (index))) {
++                              dbg_ep0(0, "Invalid string index %u\n", index);
+                               return -1;
+                       }
+                       /*dbg_ep0(3, "string_descriptor: %p", string_descriptor); */
+@@ -495,6 +396,8 @@
+       /* handle USB Standard Request (c.f. USB Spec table 9-2) */
+       if ((request->bmRequestType & USB_REQ_TYPE_MASK) != 0) {
++              if (device->device_state <= STATE_CONFIGURED)
++                      return device->cdc_recv_setup(request, urb);
+               dbg_ep0 (1, "non standard request: %x",
+                        request->bmRequestType & USB_REQ_TYPE_MASK);
+               return -1;      /* Stall here */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/unbusy-i2c.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/unbusy-i2c.patch
new file mode 100644 (file)
index 0000000..680b301
--- /dev/null
@@ -0,0 +1,88 @@
+board/neo1973/gta01/gta01.c: added logic to detect pending PMU interrupts
+board/neo1973/gta01/gta01.c (neo1973_new_second, neo1973_on_key_pressed): only
+  poll PMU if there is a pending interrupt
+board/neo1973/gta01/pcf50606.c (pcf50606_initial_regs): cleared (unmasked)
+  SECONDM in INT1M
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/board/neo1973/gta01/gta01.c
+===================================================================
+--- u-boot.orig/board/neo1973/gta01/gta01.c
++++ u-boot/board/neo1973/gta01/gta01.c
+@@ -375,19 +375,60 @@
+ #endif
+ }
++static int pwr_int_pending(void)
++{
++      S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++#if defined(CONFIG_ARCH_GTA01B_v4)
++      return !(gpio->GPGDAT & (1 << 1));      /* EINT9/GPG1 */
++#else
++      return !(gpio->GPGDAT & (1 << 8));      /* EINT16/GPG8 */
++#endif /* !CONFIG_ARCH_GTA01B_v4 */
++}
++
++static int have_int1(uint8_t mask)
++{
++      static uint8_t pending = 0;
++
++      if (pwr_int_pending()) {
++              /*
++               * We retrieve all interupts, so that we clear any stray ones
++               * in INT2 and INT3.
++               */
++              uint8_t int1,int2,int3;
++
++              int1 = pcf50606_reg_read(PCF50606_REG_INT1);
++              int2 = pcf50606_reg_read(PCF50606_REG_INT2);
++              int3 = pcf50606_reg_read(PCF50606_REG_INT3);
++              pending |= int1;
++      }
++      if (!(pending & mask))
++              return 0;
++      pending &= ~mask;
++      return 1;
++}
++
+ int neo1973_new_second(void)
+ {
+-      return pcf50606_reg_read(PCF50606_REG_INT1) & PCF50606_INT1_SECOND;
++      return have_int1(PCF50606_INT1_SECOND);
+ }
+ int neo1973_on_key_pressed(void)
+ {
+-      return !(pcf50606_reg_read(PCF50606_REG_OOCS) & PFC50606_OOCS_ONKEY);
++      static int pressed = -1;
++
++      if (pressed == -1 ||
++          have_int1(PCF50606_INT1_ONKEYF | PCF50606_INT1_ONKEYR)) {
++              pressed = !(pcf50606_reg_read(PCF50606_REG_OOCS) &
++                   PFC50606_OOCS_ONKEY);
++}
++      return pressed;
+ }
+ int neo1973_aux_key_pressed(void)
+ {
+       S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
+       if (gpio->GPFDAT & (1 << 6))
+               return 0;
+       return 1;
+Index: u-boot/board/neo1973/gta01/pcf50606.c
+===================================================================
+--- u-boot.orig/board/neo1973/gta01/pcf50606.c
++++ u-boot/board/neo1973/gta01/pcf50606.c
+@@ -6,7 +6,7 @@
+ const u_int8_t pcf50606_initial_regs[__NUM_PCF50606_REGS] = {
+       [PCF50606_REG_OOCS]     = 0x00,
+       /* gap */
+-      [PCF50606_REG_INT1M]    = PCF50606_INT1_SECOND,
++      [PCF50606_REG_INT1M]    = 0x00,
+       [PCF50606_REG_INT2M]    = 0x00,
+       [PCF50606_REG_INT3M]    = PCF50606_INT3_TSCPRES,
+       [PCF50606_REG_OOCC1]    = PCF50606_OOCC1_RTCWAK |
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/usbdcore-multiple_configs.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/usbdcore-multiple_configs.patch
new file mode 100644 (file)
index 0000000..3392896
--- /dev/null
@@ -0,0 +1,63 @@
+This patch fixes bugs in usbdcore*.c related to the use of devices
+with multiple configurations.
+
+The original code made mistakes about the meaning of configuration value and
+configuration index, and the resulting off-by-one errors resulted in:
+
+* SET_CONFIGURATION always selected the first configuration, no matter what
+  wValue is being passed.
+* GET_DESCRIPTOR/CONFIGURATION always returned the descriptor for the first
+  configuration (index 0).
+
+Signed-off-by: Harald Welte <laforge@openmoko.org>
+
+Index: u-boot/drivers/usbdcore_ep0.c
+===================================================================
+--- u-boot.orig/drivers/usbdcore_ep0.c 2007-03-14 20:29:05.000000000 +0100
++++ u-boot/drivers/usbdcore_ep0.c      2007-03-14 20:29:06.000000000 +0100
+@@ -233,8 +233,8 @@
+                               return -1;
+                       }
+                       /*dbg_ep0(2, "%d %d", index, device_descriptor->bNumConfigurations); */
+-                      if (index > device_descriptor->bNumConfigurations) {
+-                              dbg_ep0 (0, "index too large: %d > %d", index,
++                      if (index >= device_descriptor->bNumConfigurations) {
++                              dbg_ep0 (0, "index too large: %d >= %d", index,
+                                        device_descriptor->
+                                        bNumConfigurations);
+                               return -1;
+@@ -593,13 +593,8 @@
+               case USB_REQ_SET_CONFIGURATION:
+                       /* c.f. 9.4.7 - the top half of wValue is reserved */
+-                      /* */
+-                      if ((device->configuration =
+-                           le16_to_cpu (request->wValue) & 0x7f) != 0) {
+-                              /* c.f. 9.4.7 - zero is the default or addressed state, in our case this */
+-                              /* is the same is configuration zero */
+-                              device->configuration = 0;      /* TBR - ?????? */
+-                      }
++                      device->configuration = le16_to_cpu(request->wValue) & 0xff;
++
+                       /* reset interface and alternate settings */
+                       device->interface = device->alternate = 0;
+Index: u-boot/drivers/usbdcore.c
+===================================================================
+--- u-boot.orig/drivers/usbdcore.c     2007-03-14 20:29:05.000000000 +0100
++++ u-boot/drivers/usbdcore.c  2007-03-14 20:37:37.000000000 +0100
+@@ -147,12 +147,9 @@
+ static struct usb_configuration_instance *usbd_device_configuration_instance (struct usb_device_instance *device,
+               unsigned int port, unsigned int configuration)
+ {
+-      /* XXX */
+-      configuration = configuration ? configuration - 1 : 0;
+-
+-      if (configuration >= device->configurations) {
++      if (configuration >= device->configurations)
+               return NULL;
+-      }
++
+       return device->configuration_instance_array + configuration;
+ }
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/wakeup-reason-nand-only.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/wakeup-reason-nand-only.patch
new file mode 100644 (file)
index 0000000..132a9f8
--- /dev/null
@@ -0,0 +1,68 @@
+This patch should get rid of spurious poweroff after booting from RAM.
+Experimental.
+
+cpu/arm920t/start.S: record in global variable "booted_from_nand" whether we
+  booted from NAND or not
+board/neo1973/neo1973.c (board_late_init): if booted from RAM, assume that
+  wakeup cause was "reset", and skip poweroff check
+
+- Werner Almesberger <werner@openmoko.org>
+
+Index: u-boot/board/neo1973/gta01/gta01.c
+===================================================================
+--- u-boot.orig/board/neo1973/gta01/gta01.c
++++ u-boot/board/neo1973/gta01/gta01.c
+@@ -226,12 +226,16 @@
+ int board_late_init(void)
+ {
++      extern unsigned char booted_from_nand;
+       unsigned char tmp;
+       char buf[32];
+       /* Initialize the Power Management Unit with a safe register set */
+       pcf50606_init();
++      if (!booted_from_nand)
++              goto woken_by_reset;
++
+       /* obtain wake-up reason, save INT1 in environment */
+       tmp = pcf50606_reg_read(PCF50606_REG_INT1);
+       sprintf(buf, "0x%02x", tmp);
+@@ -274,6 +278,7 @@
+               neo1973_poweroff();
+       }
++woken_by_reset:
+       /* if there's no other reason, must be regular reset */
+       neo1973_wakeup_cause = NEO1973_WAKEUP_RESET;
+Index: u-boot/cpu/arm920t/start.S
+===================================================================
+--- u-boot.orig/cpu/arm920t/start.S
++++ u-boot/cpu/arm920t/start.S
+@@ -77,6 +77,14 @@
+  *************************************************************************
+  */
++#ifdef CONFIG_S3C2410_NAND_BOOT
++.globl        booted_from_nand
++booted_from_nand:
++      .word   0
++_booted_from_nand:
++      .word   booted_from_nand
++#endif /* CONFIG_S3C2410_NAND_BOOT */
++
+ _TEXT_BASE:
+       .word   TEXT_BASE
+@@ -281,6 +289,9 @@
+ #endif
+ 1:    b       1b
+ done_nand_read:
++      ldr     r0, _booted_from_nand
++      mov     r1, #1
++      strb    r1, [r0]
+ #endif /* CONFIG_S3C2410_NAND_BOOT */
+ done_relocate:
+ #endif /* CONFIG_SKIP_RELOCATE_UBOOT */
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native_oe.bb b/meta/packages/uboot/u-boot-mkimage-openmoko-native_oe.bb
new file mode 100644 (file)
index 0000000..d0d47d8
--- /dev/null
@@ -0,0 +1,83 @@
+require uboot-openmoko_svn.bb
+
+PV = "1.2.0+git9912121f7ed804ea58fd62f3f230b5dcfc357d88svn2238"
+
+SRC_URI = "git://www.denx.de/git/u-boot.git/;protocol=git;tag=9912121f7ed804ea58fd62f3f230b5dcfc357d88 \
+file://uboot-machtypes.patch;patch=1 \
+file://ext2load_hex.patch;patch=1 \
+file://uboot-s3c2410-warnings-fix.patch;patch=1 \
+file://uboot-strtoul.patch;patch=1 \
+file://uboot-cramfs_but_no_jffs2.patch;patch=1 \
+file://nand-read_write_oob.patch;patch=1 \
+file://uboot-arm920t-gd_in_irq.patch;patch=1 \
+file://uboot-arm920_s3c2410_irq_demux.patch;patch=1 \
+file://uboot-s3c2410-nand.patch;patch=1 \
+file://uboot-cmd_s3c2410.patch;patch=1 \
+file://uboot-s3c2410-mmc.patch;patch=1 \
+file://env_nand_oob.patch;patch=1 \
+file://dynenv-harden.patch;patch=1 \
+file://uboot-s3c2410_fb.patch;patch=1 \
+file://uboot-20061030-qt2410.patch;patch=1 \
+file://uboot-20061030-neo1973.patch;patch=1 \
+file://uboot-s3c2410-misccr-definitions.patch;patch=1 \
+file://boot-from-ram-reloc.patch;patch=1 \
+file://boot-from-ram-and-nand.patch;patch=1 \
+file://wakeup-reason-nand-only.patch;patch=1 \
+file://uboot-neo1973-resume.patch;patch=1 \
+file://nand-dynamic_partitions.patch;patch=1 \
+file://uboot-s3c2410-norelocate_irqvec_cpy.patch;patch=1 \
+file://uboot-usbtty-acm.patch;patch=1 \
+file://uboot-s3c2410_udc.patch;patch=1 \
+file://bbt-create-optional.patch;patch=1 \
+file://nand-createbbt.patch;patch=1 \
+file://dontask.patch;patch=1 \
+file://nand-badisbad.patch;patch=1 \
+file://uboot-bbt-quiet.patch;patch=1 \
+file://raise-limits.patch;patch=1 \
+file://splashimage-command.patch;patch=1 \
+file://cmd-unzip.patch;patch=1 \
+file://enable-splash-bmp.patch;patch=1 \
+file://preboot-override.patch;patch=1 \
+file://lowlevel_foo.patch;patch=1 \
+file://default-env.patch;patch=1 \
+file://console-ansi.patch;patch=1 \
+file://boot-menu.patch;patch=1 \
+file://uboot-dfu.patch;patch=1 \
+file://uboot-neo1973-defaultenv.patch;patch=1 \
+file://uboot-nand-markbad-reallybad.patch;patch=1 \
+file://usbdcore-multiple_configs.patch;patch=1 \
+file://neo1973-chargefast.patch;patch=1 \
+file://uboot-s3c2440.patch;patch=1 \
+file://uboot-smdk2440.patch;patch=1 \
+file://uboot-hxd8.patch;patch=1 \
+file://uboot-license.patch;patch=1 \
+file://uboot-gta02.patch;patch=1 \
+file://uboot-s3c2443.patch;patch=1 \
+file://uboot-smdk2443.patch;patch=1 \
+file://unbusy-i2c.patch;patch=1 \
+file://makefile-no-dirafter.patch;patch=1 \
+"
+
+PROVIDES = ""
+TARGET_LDFLAGS = ""
+
+do_quilt() {
+:
+}
+
+do_compile () {
+        chmod +x board/neo1973/gta01/split_by_variant.sh
+        oe_runmake gta01bv3_config
+        oe_runmake clean
+        oe_runmake tools
+}
+
+do_deploy () {
+        install -m 0755 tools/mkimage ${STAGING_BINDIR_NATIVE}/uboot-mkimage
+        ln -sf ${STAGING_BINDIR_NATIVE}/uboot-mkimage ${STAGING_BINDIR_NATIVE}/mkimage
+}
+
+do_deploy[dirs] = "${S}"
+addtask deploy before do_package after do_install
+
+
diff --git a/meta/packages/uboot/uboot-gta01_svn.bb b/meta/packages/uboot/uboot-gta01_svn.bb
deleted file mode 100644 (file)
index 89ebef6..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-DESCRIPTION = "U-boot bootloader w/ Neo1973 (GTA01) support"
-AUTHOR = "Harald Welte <laforge@openmoko.org>"
-LICENSE = "GPL"
-SECTION = "bootloader"
-PRIORITY = "optional"
-PV = "1.2.0+svn${SRCDATE}"
-PR = "r5"
-SRCDATE = "20070711"
-
-PROVIDES = "virtual/bootloader"
-S = "${WORKDIR}/git"
-
-SRC_URI = "git://www.denx.de/git/u-boot.git/;protocol=git;tag=8993e54b6f397973794f3d6f47d3b3c0c98dd4f6 \
-           svn://svn.openmoko.org/trunk/src/target/u-boot;module=patches;proto=http \
-          file://fix-arm920t-eabi.patch;patch=1"
-
-EXTRA_OEMAKE = "CROSS_COMPILE=${TARGET_PREFIX}"
-TARGET_LDFLAGS = ""
-UBOOT_MACHINES = "gta01v3 gta01v4 gta01bv2 gta01bv3"
-
-do_quilt() {
-        mv ${WORKDIR}/patches ${S}/patches 
-        cd ${S}
-        quilt push -av
-        rm -Rf patches .pc
-}
-
-do_compile () {
-       chmod +x board/neo1973/split_by_variant.sh
-       for type in ram nand
-       do
-               for mach in ${UBOOT_MACHINES}
-               do
-                       oe_runmake ${mach}_config
-                       oe_runmake clean
-                       if [ ${type} == "ram" ]; then
-                               echo 'PLATFORM_RELFLAGS += -DBUILD_FOR_RAM' >> board/neo1973/config.tmp
-                       fi
-                       oe_runmake all
-                       mv u-boot.bin u-boot_${mach}_${type}.bin
-               done
-       done
-}
-
-do_deploy () {
-       install -d ${DEPLOY_DIR_IMAGE}
-       for type in nand ram
-       do
-               for mach in ${UBOOT_MACHINES}
-               do
-                       install ${S}/u-boot_${mach}_${type}.bin ${DEPLOY_DIR_IMAGE}/u-boot_${type}-${mach}-${DATETIME}.bin
-               done
-       done
-       install -m 0755 tools/mkimage ${STAGING_BINDIR_NATIVE}/uboot-mkimage
-}
-
-do_deploy[dirs] = "${S}"
-addtask deploy before do_build after do_compile
-addtask quilt before do_patch after do_unpack
diff --git a/meta/packages/uboot/uboot-openmoko_svn.bb b/meta/packages/uboot/uboot-openmoko_svn.bb
new file mode 100644 (file)
index 0000000..3669b40
--- /dev/null
@@ -0,0 +1,85 @@
+DESCRIPTION = "U-boot bootloader w/ Neo1973 (GTA01) support"
+AUTHOR = "Harald Welte <laforge@openmoko.org>"
+LICENSE = "GPL"
+SECTION = "bootloader"
+PRIORITY = "optional"
+PROVIDES = "virtual/bootloader"
+PV = "1.2.0+git${SRCDATE}+svnr${SRCREV}"
+PR = "r1"
+
+SRCREV_FORMAT = "patches"
+
+UBOOT_MACHINES = "gta01bv2 gta01bv3 gta01bv4 smdk2440 hxd8 qt2410 gta02v1 gta02v2"
+
+DEFAULT_PREFERENCE = "-1"
+
+SRC_URI = "\
+  git://www.denx.de/git/u-boot.git/;protocol=git;name=upstream \
+  svn://svn.openmoko.org/trunk/src/target/u-boot;module=patches;proto=http;name=patches \
+  file://uboot-eabi-fix-HACK.patch \
+  file://uboot-20070311-tools_makefile_ln_sf.patch;patch=1 \
+"
+S = "${WORKDIR}/git"
+
+EXTRA_OEMAKE = "CROSS_COMPILE=${TARGET_PREFIX}"
+TARGET_LDFLAGS = ""
+
+do_quilt() {
+        mv ${WORKDIR}/patches ${S}/patches && cd ${S} && quilt push -av
+        rm -Rf patches .pc
+}
+
+do_svnrev() {
+       mv -f tools/setlocalversion tools/setlocalversion.old
+        echo -n "echo " >>tools/setlocalversion
+       echo ${PV}      >>tools/setlocalversion
+}
+
+do_configure_prepend() {
+       find . -name "*.mk" -exec sed -i 's,-mabi=apcs-gnu,,' {} \;
+       find . -name "Makefile" -exec sed -i 's,-mabi=apcs-gnu,,' {} \;
+       cat ${WORKDIR}/uboot-eabi-fix-HACK.patch |patch -p1
+}
+
+do_compile () {
+        chmod +x board/neo1973/gta*/split_by_variant.sh
+        for mach in ${UBOOT_MACHINES}
+        do
+                oe_runmake ${mach}_config
+                oe_runmake clean
+                find board -name lowlevel_foo.bin -exec rm '{}' \;
+                oe_runmake all
+                oe_runmake u-boot.udfu
+                if [ -f u-boot.udfu ]; then
+                        mv u-boot.udfu u-boot_${mach}.bin
+                else
+                        mv u-boot.bin u-boot_${mach}.bin
+                fi
+                if [ -f board/${mach}/lowlevel_foo.bin ]; then
+                        mv board/${mach}/lowlevel_foo.bin \
+                            lowlevel_foo_${mach}.bin
+                else
+                        find board -name lowlevel_foo.bin \
+                            -exec mv '{}' lowlevel_foo_${mach}.bin \;
+                fi
+        done
+}
+
+do_deploy () {
+       install -d ${DEPLOY_DIR_IMAGE}
+       for mach in ${UBOOT_MACHINES}
+       do
+               install -m 0644 ${S}/u-boot_${mach}.bin ${DEPLOY_DIR_IMAGE}/u-boot-${mach}-${PV}-${PR}.bin
+               ln -sf ${DEPLOY_DIR_IMAGE}/u-boot-${mach}-${PV}-${PR}.bin ${DEPLOY_DIR_IMAGE}/uboot-${mach}-latest.bin
+               if [ -f ${S}/lowlevel_foo_${mach}.bin ]; then
+                       install -m 0644 ${S}/lowlevel_foo_${mach}.bin ${DEPLOY_DIR_IMAGE}/lowlevel_foo-${mach}-${PV}-${PR}.bin
+                       ln -sf ${DEPLOY_DIR_IMAGE}/lowlevel_foo-${mach}-${PV}-${PR}.bin ${DEPLOY_DIR_IMAGE}/lowlevel-foo-${mach}-latest.bin
+               fi
+       done
+       install -m 0755 tools/mkimage ${STAGING_BINDIR_NATIVE}/uboot-mkimage
+}
+
+do_deploy[dirs] = "${S}"
+addtask deploy before do_package after do_install
+addtask quilt before do_patch after do_unpack
+addtask svnrev before do_patch after do_quilt