s5p6442: smdk6442: initial work
authorJoonyoung Shim <jy0922.shim@samsung.com>
Wed, 13 Jan 2010 04:20:53 +0000 (13:20 +0900)
committerJoonyoung Shim <jy0922.shim@samsung.com>
Wed, 13 Jan 2010 04:54:13 +0000 (13:54 +0900)
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
41 files changed:
Makefile
board/samsung/smdk6442/Makefile [new file with mode: 0644]
board/samsung/smdk6442/config.mk [new file with mode: 0644]
board/samsung/smdk6442/lowlevel_init.S [new file with mode: 0644]
board/samsung/smdk6442/mem_setup.S [new file with mode: 0644]
board/samsung/smdk6442/onenand.c [new file with mode: 0644]
board/samsung/smdk6442/smdk6442.c [new file with mode: 0644]
common/serial.c
cpu/arm1176/cpu.c
cpu/arm1176/s5p64xx/Makefile [new file with mode: 0644]
cpu/arm1176/s5p64xx/clock.c [new file with mode: 0644]
cpu/arm1176/s5p64xx/cpu_info.c [new file with mode: 0644]
cpu/arm1176/s5p64xx/gpio.c [new file with mode: 0644]
cpu/arm1176/s5p64xx/i2c-gpio.c [new file with mode: 0644]
cpu/arm1176/s5p64xx/reset.S [new file with mode: 0644]
cpu/arm1176/s5p64xx/sleep.c [new file with mode: 0644]
cpu/arm1176/s5p64xx/sleep.h [new file with mode: 0644]
cpu/arm1176/s5p64xx/sleep_asm.S [new file with mode: 0644]
cpu/arm1176/s5p64xx/timer.c [new file with mode: 0644]
cpu/arm1176/s5p64xx/usb-hs-otg.c [new file with mode: 0644]
cpu/arm1176/s5p64xx/usb-hs-otg.h [new file with mode: 0644]
cpu/arm1176/s5p64xx/usb_downloader.c [new file with mode: 0644]
cpu/arm1176/start.S
drivers/serial/Makefile
drivers/serial/serial_s5pc1xx.c
include/asm-arm/arch-s5p64xx/clk.h [new file with mode: 0644]
include/asm-arm/arch-s5p64xx/clock.h [new file with mode: 0644]
include/asm-arm/arch-s5p64xx/cpu.h [new file with mode: 0644]
include/asm-arm/arch-s5p64xx/gpio.h [new file with mode: 0644]
include/asm-arm/arch-s5p64xx/i2c.h [new file with mode: 0644]
include/asm-arm/arch-s5p64xx/keypad.h [new file with mode: 0644]
include/asm-arm/arch-s5p64xx/mem.h [new file with mode: 0644]
include/asm-arm/arch-s5p64xx/mmc.h [new file with mode: 0644]
include/asm-arm/arch-s5p64xx/power.h [new file with mode: 0644]
include/asm-arm/arch-s5p64xx/pwm.h [new file with mode: 0644]
include/asm-arm/arch-s5p64xx/regs-fb.h [new file with mode: 0644]
include/asm-arm/arch-s5p64xx/sys_proto.h [new file with mode: 0644]
include/asm-arm/arch-s5p64xx/uart.h [new file with mode: 0644]
include/asm-arm/arch-s5p64xx/usb-hs-otg.h [new file with mode: 0644]
include/configs/smdk6442.h [new file with mode: 0644]
include/serial.h

index 4a00934..5c0b984 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3295,6 +3295,9 @@ smdk6400_config   :       unconfig
        fi
        @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
 
+smdk6442_config:       unconfig
+       @$(MKCONFIG) $(@:_config=) arm arm1176 smdk6442 samsung s5p64xx
+
 #========================================================================
 # i386
 #========================================================================
diff --git a/board/samsung/smdk6442/Makefile b/board/samsung/smdk6442/Makefile
new file mode 100644 (file)
index 0000000..9700ffb
--- /dev/null
@@ -0,0 +1,55 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@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-y        := smdk6442.o
+COBJS-$(CONFIG_SAMSUNG_ONENAND)        += onenand.o
+SOBJS  := lowlevel_init.o
+
+SRCS    := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS-y))
+SOBJS  := $(addprefix $(obj),$(SOBJS))
+
+$(LIB):        $(obj).depend $(SOBJS) $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(SOBJS) $(OBJS)
+
+clean:
+       rm -f $(SOBJS) $(OBJS)
+
+distclean:     clean
+       rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/samsung/smdk6442/config.mk b/board/samsung/smdk6442/config.mk
new file mode 100644 (file)
index 0000000..453e034
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Copyright (C) 2010 Samsung Elecgtronics
+# Minkyu Kang <mk7.kang@samsung.com>
+#
+
+TEXT_BASE = 0x24800000
diff --git a/board/samsung/smdk6442/lowlevel_init.S b/board/samsung/smdk6442/lowlevel_init.S
new file mode 100644 (file)
index 0000000..2167795
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <version.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/power.h>
+
+/*
+ * Register usages:
+ *
+ * r5 has zero always
+ */
+
+_TEXT_BASE:
+       .word   TEXT_BASE
+
+       .globl lowlevel_init
+lowlevel_init:
+       mov     r9, lr
+
+       /* r5 has always zero */
+       mov     r5, #0
+
+       ldr     r8, =S5P6442_GPIO_BASE
+
+       /* IO retension release */
+       ldr     r0, =S5P6442_OTHERS                     @0xE010E000
+       ldr     r1, [r0]
+       ldreq   r2, =(1 << 31)                          @IO_RET_REL
+       ldrne   r2, =((1 << 31) | (1 << 29) | (1 << 28))        @ GPIO, UART_IO
+       orr     r1, r1, r2
+       str     r1, [r0]
+
+#ifndef CONFIG_ONENAND_IPL
+       /* Disable Watchdog */
+       ldr     r0, =S5P6442_WATCHDOG_BASE              @0xEA200000
+       orr     r0, r0, #0x0
+       str     r5, [r0]
+
+       /* setting SRAM */
+       ldr     r0, =S5P6442_SROMC_BASE
+       ldr     r1, =0x9
+       str     r1, [r0]
+#endif
+
+       /* S5P6442 has 3 groups of interrupt sources */
+       ldr     r0, =S5P6442_VIC0_BASE                  @0xE4000000
+       ldr     r1, =S5P6442_VIC1_BASE                  @0xE4000000
+       ldr     r2, =S5P6442_VIC2_BASE                  @0xE4000000
+
+       /* Disable all interrupts (VIC0, VIC1 and VIC2) */
+       mvn     r3, #0x0
+       str     r3, [r0, #0x14]                         @INTENCLEAR
+       str     r3, [r1, #0x14]                         @INTENCLEAR
+       str     r3, [r2, #0x14]                         @INTENCLEAR
+
+#ifndef CONFIG_ONENAND_IPL
+       /* Set all interrupts as IRQ */
+       str     r5, [r0, #0xc]                          @INTSELECT
+       str     r5, [r1, #0xc]                          @INTSELECT
+       str     r5, [r2, #0xc]                          @INTSELECT
+
+       /* Pending Interrupt Clear */
+       str     r5, [r0, #0xf00]                        @INTADDRESS
+       str     r5, [r1, #0xf00]                        @INTADDRESS
+       str     r5, [r2, #0xf00]                        @INTADDRESS
+#endif
+
+#ifndef CONFIG_ONENAND_IPL
+       /* for UART */
+       bl uart_asm_init
+#endif
+
+#ifdef CONFIG_ONENAND_IPL
+       /* init system clock */
+       bl      system_clock_init
+
+       bl      mem_ctrl_asm_init
+
+       /* Wakeup support. Don't know if it's going to be used, untested. */
+       ldr     r0, =S5P6442_RST_STAT
+       ldr     r1, [r0]
+       bic     r1, r1, #0xfffffff7
+       cmp     r1, #0x8
+       beq     wakeup_reset
+#endif
+
+1:
+       mov     lr, r9
+       mov     pc, lr
+
+#ifdef CONFIG_ONENAND_IPL
+wakeup_reset:
+
+       /* Clear wakeup status register */
+       ldr     r0, =S5P6442_WAKEUP_STAT
+       ldr     r1, [r0]
+       str     r1, [r0]
+
+       /* Load return address and jump to kernel */
+       ldr     r0, =S5P6442_INFORM0
+
+       /* r1 = physical address of s5p6442_cpu_resume function */
+       ldr     r1, [r0]
+
+       /* Jump to kernel (sleep.S) */
+       mov     pc, r1
+       nop
+       nop
+#endif
+
+/*
+ * system_clock_init: Initialize core clock and bus clock.
+ * void system_clock_init(void)
+ */
+system_clock_init:
+       ldr     r8, =S5P64XX_CLOCK_BASE         @ 0xE0100000
+
+       /* Set Clock divider */
+       ldr     r1, =0x10100000
+       str     r1, [r8, #0x300]
+
+       /* Set Lock Time */
+       ldr     r1, =0xe10                      @ Locktime : 0xe10 = 3600
+       str     r1, [r8, #0x000]                @ APLL_LOCK
+       str     r1, [r8, #0x008]                @ MPLL_LOCK
+       str     r1, [r8, #0x010]                @ EPLL_LOCK
+       str     r1, [r8, #0x020]                @ VPLL_LOCK
+
+       /* APLL_CON */
+       ldr     r1, =0x82150c01         @ SDIV 1, PDIV 0xc, MDIV 0x215
+       str     r1, [r8, #0x100]
+       /* MPLL_CON */
+       ldr     r1, =0x810a0303         @ SDIV 3, PDIV 3, MDIV 0x10a
+       str     r1, [r8, #0x108]
+       /* EPLL_CON */
+       ldr     r1, =0x80600303         @ SDIV 3, PDIV 3, MDIV 0x60
+       str     r1, [r8, #0x110]
+       /* VPLL_CON */
+       ldr     r1, =0x806c0303         @ SDIV 3, PDIV 3, MDIV 0x6c
+       str     r1, [r8, #0x120]
+
+       /* Set Source Clock */
+       ldr     r1, =0x1111                     @ A, M, E, VPLL Muxing
+       str     r1, [r8, #0x200]                @ CLK_SRC0
+
+       /* wait at least 200us to stablize all clock */
+       mov     r2, #0x10000
+1:     subs    r2, r2, #1
+       bne     1b
+
+       mov     pc, lr
+
+#ifndef CONFIG_ONENAND_IPL
+/*
+ * uart_asm_init: Initialize UART's pins
+ */
+uart_asm_init:
+       mov     r0, r8
+       ldr     r1, =0x22222222
+       str     r1, [r0, #0x0]                  @ GPA0_CON
+       ldr     r1, =0x00022222
+       str     r1, [r0, #0x20]                 @ GPA1_CON
+
+       mov     pc, lr
+#endif
diff --git a/board/samsung/smdk6442/mem_setup.S b/board/samsung/smdk6442/mem_setup.S
new file mode 100644 (file)
index 0000000..741d894
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Originates from Samsung's u-boot 1.1.6 port to S5PC1xx
+ *
+ * Copyright (C) 2009 Samsung Electrnoics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+       .globl mem_ctrl_asm_init
+mem_ctrl_asm_init:
+       ldr     r6, =S5P5442_DMC_BASE                   @ 0xE6000000
+
+       /* DLL parameter setting */
+       ldr     r1, =0x00141408
+       str     r1, [r6, #0x018]                        @ PHYCONTROL0
+       ldr     r1, =0x00008044
+       str     r1, [r6, #0x01C]                        @ PHYCONTROL1
+       ldr     r1, =0x0
+       str     r1, [r6, #0x020]                        @ PHYCONTROL2
+
+       /* DLL on */
+       ldr     r1, =0x0014140a
+       str     r1, [r6, #0x018]                        @ PHYCONTROL0
+
+       /* DLL start */
+       ldr     r1, =0x0014140b
+       str     r1, [r6, #0x018]                        @ PHYCONTROL0
+
+       /* Force value locking for DLL off */
+       str     r1, [r6, #0x018]                        @ PHYCONTROL0
+
+       /* DLL off */
+       ldr     r1, =0x00141409
+       str     r1, [r6, #0x018]                        @ PHYCONTROL0
+
+       /* auto refresh off */
+       ldr     r1, =0x0f0010d0
+       str     r1, [r6, #0x000]                        @ CONCONTROL
+
+       /*
+        * Burst Length 4, 2 chips, 32-bit, LPDDR
+        * OFF: dynamic self refresh, force precharge, dynamic power down off
+        */
+       ldr     r1, =0x00202100
+       str     r1, [r6, #0x004]                        @ MEMCONTROL
+
+       /*
+        * Note:
+        * If Bank0 has OneDRAM we place it at 0x2800'0000
+        * So finally Bank1 should address start at at 0x2000'0000
+        */
+       mov     r4, #0x0
+
+#if 0
+swap_memory:
+       /*
+        * Bank0
+        * 0x30 -> 0x30000000
+        * 0xf8 -> 0x37FFFFFF
+        * [15:12] 0: Linear
+        * [11:8 ] 2: 9 bits
+        * [ 7:4 ] 2: 14 bits
+        * [ 3:0 ] 2: 4 banks
+        */
+       ldr     r1, =0x30f80222
+       /* if r4 is 1, swap the bank */
+       cmp     r4, #0x1
+       orreq   r1, r1, #0x08000000
+       str     r1, [r6, #0x008]                        @ MEMCONFIG0
+
+       /*
+        * Bank1
+        * 0x38 -> 0x38000000
+        * 0xf8 -> 0x3fFFFFFF
+        * [15:12] 0: Linear
+        * [11:8 ] 2: 9 bits
+        * [ 7:4 ] 2: 14 bits
+        * [ 3:0 ] 2: 4 banks
+        */
+       ldr     r1, =0x38f80222
+       /* if r4 is 1, swap the bank */
+       cmp     r4, #0x1
+       biceq   r1, r1, #0x08000000
+       str     r1, [r6, #0x00c]                        @ MEMCONFIG1
+
+       ldr     r1, =0x20000000
+       str     r1, [r6, #0x014]                        @ PRECHCONFIG
+#endif
+
+       /*
+        * FIXME: Please verify these values
+        * 7.8us * 166MHz %LE %LONG1294(0x50E)
+        * 7.8us * 133MHz %LE %LONG1038(0x40E),
+        * 7.8us * 100MHz %LE %LONG780(0x30C),
+        * 7.8us * 20MHz  %LE %LONG156(0x9C),
+        * 7.8us * 10MHz  %LE %LONG78(0x4E)
+        */
+       ldr     r1, =0x0000040e
+       str     r1, [r6, #0x030]                        @ TIMINGAREF
+
+       /* 166 MHz */
+       ldr     r1, =0x0c233286
+       str     r1, [r6, #0x034]                        @ TIMINGROW
+
+       /* twtr=3 twr=2 trtp=3 cl=3 wl=3 rl=3 */
+       ldr     r1, =0x12130005
+       str     r1, [r6, #0x038]                        @ TIMINGDATA
+
+       /* tfaw=4 sxsr=0x14 txp=0x14 tcke=3 tmrd=3 */
+       ldr     r1, =0x0e120222
+       str     r1, [r6, #0x03C]                        @ TIMINGPOWER
+
+       /* chip0 Deselect */
+       ldr     r1, =0x07000000
+       str     r1, [r6, #0x010]                        @ DIRECTCMD
+
+       /* chip0 PALL */
+       ldr     r1, =0x01000000
+       str     r1, [r6, #0x010]                        @ DIRECTCMD
+
+       /* chip0 REFA */
+       ldr     r1, =0x05000000
+       str     r1, [r6, #0x010]                        @ DIRECTCMD
+       /* chip0 REFA */
+       str     r1, [r6, #0x010]                        @ DIRECTCMD
+
+       /* chip0 MRS, CL%LE %LONG3, BL%LE %LONG4 */
+       ldr     r1, =0x00000032
+       str     r1, [r6, #0x010]                        @ DIRECTCMD
+
+       /* chip1 Deselect */
+       ldr     r1, =0x07100000
+       str     r1, [r6, #0x010]                        @ DIRECTCMD
+
+       /* chip1 PALL */
+       ldr     r1, =0x01100000
+       str     r1, [r6, #0x010]                        @ DIRECTCMD
+
+       /* chip1 REFA */
+       ldr     r1, =0x05100000
+       str     r1, [r6, #0x010]                        @ DIRECTCMD
+       /* chip1 REFA */
+       str     r1, [r6, #0x010]                        @ DIRECTCMD
+
+       /* chip1 MRS, CL%LE %LONG3, BL%LE %LONG4 */
+       ldr     r1, =0x00100032
+       str     r1, [r6, #0x010]                        @ DIRECTCMD
+
+       /* auto refresh on */
+       ldr     r1, =0x0f0010f0
+       str     r1, [r6, #0x000]                        @ CONCONTROL
+
+       /* PwrdnConfig */
+       ldr     r1, =0x00100002
+       str     r1, [r6, #0x028]                        @ PWRDNCONFIG
+
+       /* BL%LE %LONG */
+       ldr     r1, =0x00212100
+       str     r1, [r6, #0x004]                        @ MEMCONTROL
+
+#if 0
+       /* Try to test memory area */
+       cmp     r4, #0x1
+       beq     1f
+
+       mov     r4, #0x1
+       ldr     r1, =0x37ffff00
+       str     r4, [r1]
+       str     r4, [r1, #0x4]                          @ dummy write
+       ldr     r0, [r1]
+       cmp     r0, r4
+       bne     swap_memory
+#endif
+
+1:
+       mov     pc, lr
+
+       .ltorg
diff --git a/board/samsung/smdk6442/onenand.c b/board/samsung/smdk6442/onenand.c
new file mode 100644 (file)
index 0000000..cfa0c46
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008-2009 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <linux/mtd/compat.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+#include <linux/mtd/samsung_onenand.h>
+
+#include <onenand_uboot.h>
+
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+
+void onenand_board_init(struct mtd_info *mtd)
+{
+#if 0
+       struct onenand_chip *this = mtd->priv;
+       struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE;
+       struct samsung_onenand *onenand;
+       int value;
+
+       this->base = (void *)S5PC100_ONENAND_BASE;
+       onenand = (struct samsung_onenand *)this->base;
+
+       /* D0 Domain memory clock gating */
+       value = readl(&clk->gate_d01);
+       value &= ~(1 << 2);             /* CLK_ONENANDC */
+       value |= (1 << 2);
+       writel(value, &clk->gate_d01);
+
+       value = readl(&clk->src0);
+       value &= ~(1 << 24);            /* MUX_1nand: 0 from HCLKD0 */
+       value &= ~(1 << 20);            /* MUX_HREF: 0 from FIN_27M */
+       writel(value, &clk->src0);
+
+       value = readl(&clk->div1);
+       value &= ~(3 << 16);            /* PCLKD1_RATIO */
+       value |= (1 << 16);
+       writel(value, &clk->div1);
+
+       writel(ONENAND_MEM_RESET_COLD, &onenand->mem_reset);
+
+       while (!(readl(&onenand->int_err_stat) & RST_CMP))
+               continue;
+
+       writel(RST_CMP, &onenand->int_err_ack);
+
+       /*
+        * Access_Clock [2:0]
+        * 166 MHz, 134 Mhz : 3
+        * 100 Mhz, 60 Mhz  : 2
+        */
+       writel(0x3, &onenand->acc_clock);
+
+       writel(INT_ERR_ALL, &onenand->int_err_mask);
+       writel(1 << 0, &onenand->int_pin_en);   /* Enable */
+
+       value = readl(&onenand->int_err_mask);
+       value &= ~RDY_ACT;
+       writel(value, &onenand->int_err_mask);
+
+       s3c_onenand_init(mtd);
+#endif
+}
diff --git a/board/samsung/smdk6442/smdk6442.c b/board/samsung/smdk6442/smdk6442.c
new file mode 100644 (file)
index 0000000..e1b319d
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (C) 2008-2009 Samsung Electronics
+ *  Minkyu Kang <mk7.kang@samsung.com>
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+       gd->bd->bi_arch_number = MACH_TYPE_SMDKC100;
+       gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
+
+       return 0;
+}
+
+int dram_init(void)
+{
+       gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+       gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1,
+                                               PHYS_SDRAM_1_SIZE);
+
+       return 0;
+}
+
+#ifdef CONFIG_DISPLAY_BOARDINFO
+int checkboard(void)
+{
+       printf("Board:\t6442\n");
+       return 0;
+}
+#endif
index 5f9ffd7..ab8e0e3 100644 (file)
@@ -69,7 +69,7 @@ struct serial_device *__default_serial_console (void)
 #else
 #error "CONFIG_SERIAL? missing."
 #endif
-#elif defined(CONFIG_S5PC1XX)
+#elif defined(CONFIG_S5PC1XX) || defined(CONFIG_S5P64XX)
 #if defined(CONFIG_SERIAL0)
        return &s5pc1xx_serial0_device;
 #elif defined(CONFIG_SERIAL1)
index 2c0014f..befa0cd 100644 (file)
@@ -33,7 +33,9 @@
 
 #include <common.h>
 #include <command.h>
+#ifdef CONFIG_S3C64XX
 #include <asm/arch/s3c6400.h>
+#endif
 #include <asm/system.h>
 
 static void cache_flush (void);
diff --git a/cpu/arm1176/s5p64xx/Makefile b/cpu/arm1176/s5p64xx/Makefile
new file mode 100644 (file)
index 0000000..0626af2
--- /dev/null
@@ -0,0 +1,58 @@
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@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$(SOC).a
+
+SOBJS  = reset.o
+#SOBJS += cache.o
+
+COBJS-y                += clock.o
+COBJS-y                += cpu_info.o
+COBJS-y                += gpio.o
+COBJS-y                += timer.o
+#COBJS-$(CONFIG_CMD_SLEEP)     += sleep.o
+#COBJS-$(CONFIG_CMD_SLEEP)     += sleep_asm.o
+COBJS-$(CONFIG_SOFT_I2C)       += i2c-gpio.o
+#COBJS-$(CONFIG_CMD_USBDOWN)   += usb-hs-otg.o usb_downloader.o
+
+SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS-y) $(SOBJS))
+
+all:    $(obj).depend $(LIB)
+
+$(LIB):        $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm1176/s5p64xx/clock.c b/cpu/arm1176/s5p64xx/clock.c
new file mode 100644 (file)
index 0000000..c289b1e
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+
+#ifndef CONFIG_SYS_CLK_FREQ_6442
+#define CONFIG_SYS_CLK_FREQ_6442       12000000
+#endif
+
+unsigned long (*get_pclk)(void);
+unsigned long (*get_arm_clk)(void);
+unsigned long (*get_pll_clk)(int);
+
+/* s5p6442: return pll clock frequency */
+static unsigned long s5p6442_get_pll_clk(int pllreg)
+{
+       struct s5p6442_clock *clk = (struct s5p6442_clock *)S5P64XX_CLOCK_BASE;
+       unsigned long r, m, p, s, mask, fout;
+       unsigned int freq;
+
+       switch (pllreg) {
+       case APLL:
+               r = readl(&clk->apll_con);
+               break;
+       case MPLL:
+               r = readl(&clk->mpll_con);
+               break;
+       case EPLL:
+               r = readl(&clk->epll_con);
+               break;
+       case VPLL:
+               r = readl(&clk->vpll_con);
+               break;
+       default:
+               printf("Unsupported PLL (%d)\n", pllreg);
+               return 0;
+       }
+
+       /*
+        * APLL_CON: MIDV [25:16]
+        * MPLL_CON: MIDV [25:16]
+        * EPLL_CON: MIDV [24:16]
+        * VPLL_CON: MIDV [24:16]
+        */
+       if (pllreg == APLL || pllreg == MPLL)
+               mask = 0x3ff;
+       else
+               mask = 0x1ff;
+
+       m = (r >> 16) & mask;
+
+       /* PDIV [13:8] */
+       p = (r >> 8) & 0x3f;
+       /* SDIV [2:0] */
+       s = r & 0x7;
+
+       freq = CONFIG_SYS_CLK_FREQ_6442;
+       if (pllreg == APLL) {
+               if (s < 1)
+                       s = 1;
+               /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */
+               fout = m * (freq / (p * (1 << (s - 1))));
+       } else
+               /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
+               fout = m * (freq / (p * (1 << s)));
+
+       return fout;
+}
+
+/* s5p6442: return ARM clock frequency */
+static unsigned long s5p6442_get_arm_clk(void)
+{
+       struct s5p6442_clock *clk = (struct s5p6442_clock *)S5P64XX_CLOCK_BASE;
+       unsigned long div;
+       unsigned long dout_apll, armclk;
+       unsigned int apll_ratio;
+
+       div = readl(&clk->div0);
+
+       /* APLL_RATIO: [2:0] */
+       apll_ratio = div & 0x7;
+
+       dout_apll = get_pll_clk(APLL) / (apll_ratio + 1);
+       armclk = dout_apll;
+
+       return armclk;
+}
+
+/* s5p6442: return D0CLK frequency */
+static unsigned long get_d0clk(void)
+{
+       struct s5p6442_clock *clk = (struct s5p6442_clock *)S5P64XX_CLOCK_BASE;
+       unsigned long d0clk;
+       uint div, d0_bus_ratio;
+
+       div = readl(&clk->div0);
+       /* D0CLK_RATIO: [19:16] */
+       d0_bus_ratio = (div >> 16) & 0xf;
+
+       d0clk = get_arm_clk() / (d0_bus_ratio + 1);
+
+       return d0clk;
+}
+
+/* s5p6442: return P1CLK frequency */
+static unsigned long get_p1clk(void)
+{
+       struct s5p6442_clock *clk = (struct s5p6442_clock *)S5P64XX_CLOCK_BASE;
+       unsigned long d1_bus, p1clk;
+       uint div, d1_bus_ratio, p1clk_ratio;
+
+       div = readl(&clk->div0);
+       /* D1CLK_RATIO: [27:24] */
+       d1_bus_ratio = (div >> 24) & 0xf;
+       /* P1CLK_RATIO: [30:28] */
+       p1clk_ratio = (div >> 28) & 0x7;
+
+       /* ASYNC Mode */
+       d1_bus = get_pll_clk(MPLL) / (d1_bus_ratio + 1);
+       p1clk = d1_bus / (p1clk_ratio + 1);
+
+       return p1clk;
+}
+
+/* s5p6442: return peripheral clock frequency */
+static unsigned long s5p6442_get_pclk(void)
+{
+       return get_p1clk();
+}
+
+void s5p64xx_clock_init(void)
+{
+       if (cpu_is_s5p6442()) {
+               get_pll_clk = s5p6442_get_pll_clk;
+               get_arm_clk = s5p6442_get_arm_clk;
+               get_pclk = s5p6442_get_pclk;
+       }
+}
diff --git a/cpu/arm1176/s5p64xx/cpu_info.c b/cpu/arm1176/s5p64xx/cpu_info.c
new file mode 100644 (file)
index 0000000..f9d0fcc
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clk.h>
+
+/* Default is s5p6442 */
+unsigned int s5p64xx_cpu_id = 0x6442;
+
+#ifdef CONFIG_ARCH_CPU_INIT
+int arch_cpu_init(void)
+{
+       s5p64xx_cpu_id = readl(S5P64XX_PRO_ID);
+       s5p64xx_cpu_id = (s5p64xx_cpu_id & 0x0FFFF000) >> 12;
+
+       s5p64xx_clock_init();
+
+       return 0;
+}
+#endif
+
+u32 get_device_type(void)
+{
+       return s5p64xx_cpu_id;
+}
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+       char buf[32];
+
+       printf("CPU:\tS5P%X@%sMHz\n",
+                       s5p64xx_cpu_id, strmhz(buf, get_arm_clk()));
+
+       return 0;
+}
+#endif
diff --git a/cpu/arm1176/s5p64xx/gpio.c b/cpu/arm1176/s5p64xx/gpio.c
new file mode 100644 (file)
index 0000000..b2b034e
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/gpio.h>
+
+#define CON_MASK(x)            (0xf << ((x) << 2))
+#define CON_SFR(x, v)          ((v) << ((x) << 2))
+
+#define DAT_MASK(x)            (0x1 << (x))
+#define DAT_SET(x)             (0x1 << (x))
+
+#define PULL_MASK(x)           (0x3 << ((x) << 1))
+#define PULL_MODE(x, v)                ((v) << ((x) << 1))
+
+#define DRV_MASK(x)            (0x3 << (x))
+#define DRV_SET(x, m)          ((m) << (x))
+#define RATE_MASK(x)           (0x1 << (x + 16))
+#define RATE_SET(x)            (0x1 << (x + 16))
+
+void gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg)
+{
+       unsigned int value;
+
+       value = readl(&bank->con);
+       value &= ~CON_MASK(gpio);
+       value |= CON_SFR(gpio, cfg);
+       writel(value, &bank->con);
+}
+
+void gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int enable)
+{
+       unsigned int value;
+
+       gpio_cfg_pin(bank, gpio, GPIO_OUTPUT);
+
+       value = readl(&bank->dat);
+       value &= ~DAT_MASK(gpio);
+       if (enable)
+               value |= DAT_SET(gpio);
+       writel(value, &bank->dat);
+}
+
+void gpio_direction_input(struct s5p_gpio_bank *bank, int gpio)
+{
+       gpio_cfg_pin(bank, gpio, GPIO_INPUT);
+}
+
+void gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int enable)
+{
+       unsigned int value;
+
+       value = readl(&bank->dat);
+       value &= ~DAT_MASK(gpio);
+       if (enable)
+               value |= DAT_SET(gpio);
+       writel(value, &bank->dat);
+}
+
+unsigned int gpio_get_value(struct s5p_gpio_bank *bank, int gpio)
+{
+       unsigned int value;
+
+       value = readl(&bank->dat);
+       return !!(value & DAT_MASK(gpio));
+}
+
+void gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode)
+{
+       unsigned int value;
+
+       value = readl(&bank->pull);
+       value &= ~PULL_MASK(gpio);
+
+       switch (mode) {
+       case GPIO_PULL_DOWN:
+       case GPIO_PULL_UP:
+               value |= PULL_MODE(gpio, mode);
+               break;
+       default:
+               break;
+       }
+
+       writel(value, &bank->pull);
+}
+
+void gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode)
+{
+       unsigned int value;
+
+       value = readl(&bank->drv);
+       value &= ~DRV_MASK(gpio);
+
+       switch (mode) {
+       case GPIO_DRV_1x:
+       case GPIO_DRV_2x:
+       case GPIO_DRV_3x:
+       case GPIO_DRV_4x:
+               value |= DRV_SET(gpio, mode);
+               break;
+       default:
+               break;
+       }
+
+       writel(value, &bank->drv);
+}
+
+void gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
+{
+       unsigned int value;
+
+       value = readl(&bank->drv);
+       value &= ~RATE_MASK(gpio);
+
+       switch (mode) {
+       case GPIO_DRV_FAST:
+       case GPIO_DRV_SLOW:
+               value |= RATE_SET(gpio);
+               break;
+       default:
+               break;
+       }
+
+       writel(value, &bank->drv);
+}
+
+#ifdef CONFIG_CMD_GPIO
+static char *gpio_name[] = {
+       "GPA0", "GPA1", "GPB", "GPC0", "GPC1", "GPD0", "GPD1", "GPE0", "GPE1",
+       "GPF0", "GPF1", "GPF2", "GPF3", "GPG0", "GPG1", "GPG2", "GPJ0", "GPJ1",
+       "GPJ2", "GPJ3", "GPJ4", "MP01", "MP02", "MP03", "MP04", "MP05", "MP06",
+       "MP07", "MP10", "MP11", "MP12", "MP13", "MP14", "MP15", "MP16", "MP17",
+       "MP18",
+};
+
+static char *gpio_name1[] = {
+       "GPH0", "GPH1", "GPH2", "GPH3",
+};
+
+static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       struct s5pc110_gpio *gpio =
+               (struct s5pc110_gpio *)S5PC110_GPIO_BASE;
+       int i = 0;
+       int j;
+
+       if (argc == 1) {
+               cmd_usage(cmdtp);
+               return 1;
+       }
+
+       if (strcmp(argv[1], "show") == 0) {
+               while (1) {
+                       printf("%s\n", gpio_name[i]);
+
+                       for (j = 0; j < 8; j++) {
+                               printf("[%d] %s", j,
+                                       gpio_get_value(&gpio->gpio_a0 + i, j) ?
+                                       "hi" : "lo");
+                               if ((j + 1) & (8 - 1))
+                                       printf("\t");
+                               else
+                                       printf("\n");
+                       }
+                       printf("\n");
+
+                       i++;
+                       if ((&gpio->gpio_a0 + i) == &gpio->res1)
+                               break;
+               }
+
+               for (i = 0; i < 4; i++) {
+                       printf("%s\n", gpio_name1[i]);
+
+                       for (j = 0; j < 8; j++) {
+                               printf("[%d] %s", j,
+                                       gpio_get_value(&gpio->gpio_h0 + i, j) ?
+                                       "hi" : "lo");
+                               if ((j + 1) & (8 - 1))
+                                       printf("\t");
+                               else
+                                       printf("\n");
+                       }
+                       printf("\n");
+               }
+
+               return 1;
+       } else if (strcmp(argv[1], "set") == 0) {
+               int num, value;
+
+               if (argc != 5) {
+                       cmd_usage(cmdtp);
+                       return 1;
+               }
+
+               if (strcmp(argv[2], "GPH0") == 0) {
+                       i = 48 + 48 + 0;
+               } else if (strcmp(argv[2], "GPH1") == 0) {
+                       i = 48 + 48 + 1;
+               } else if (strcmp(argv[2], "GPH2") == 0) {
+                       i = 48 + 48 + 2;
+               } else if (strcmp(argv[2], "GPH3") == 0) {
+                       i = 48 + 48 + 3;
+               } else {
+                       while (1) {
+                               if (strcmp(argv[2], gpio_name[i]) == 0)
+                                       break;
+                               i++;
+
+                               if ((&gpio->gpio_a0 + i) == &gpio->res1) {
+                                       printf("Can't found %s bank\n", argv[2]);
+                                       return 1;
+                               }
+                       }
+               }
+               num = simple_strtoul(argv[3], NULL, 10);
+               value = simple_strtoul(argv[4], NULL, 10);
+
+               gpio_set_value(&gpio->gpio_a0 + i, num, value);
+
+               printf("%s[%d] set to %s\n", argv[2], num,
+                               value ? "hi" : "lo");
+
+               return 1;
+       }
+
+       cmd_usage(cmdtp);
+       return 1;
+}
+
+U_BOOT_CMD(
+       gpio,           CONFIG_SYS_MAXARGS,     1, do_gpio,
+       "GPIO Control",
+       "show - show all banks\n"
+       "gpio set bank num value - set gpio value\n"
+);
+#endif
diff --git a/cpu/arm1176/s5p64xx/i2c-gpio.c b/cpu/arm1176/s5p64xx/i2c-gpio.c
new file mode 100644 (file)
index 0000000..cbe7155
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/gpio.h>
+#include <i2c-gpio.h>
+#include <i2c.h>
+
+static struct i2c_gpio_bus *i2c_gpio;
+
+void i2c_gpio_init(struct i2c_gpio_bus *bus, int len, int index)
+{
+       int i;
+       struct s5p_gpio_bank *bank;
+
+       i2c_gpio = bus;
+
+       /* init all i2c gpio buses */
+       for (i = 0; i < len; i++) {
+               bank = (struct s5p_gpio_bank *)i2c_gpio[i].bus->gpio_base;
+
+               /* SDA */
+               gpio_direction_output(bank,
+                               i2c_gpio[i].bus->sda_pin, 1);
+
+               /* SCL */
+               gpio_direction_output(bank,
+                               i2c_gpio[i].bus->scl_pin, 1);
+       }
+
+       /* set default bus */
+       i2c_set_bus_num(index);
+}
+
+void i2c_gpio_set(int line, int value)
+{
+       struct s5p_gpio_bank *bank;
+       unsigned int bus_index;
+
+       bus_index = i2c_get_bus_num();
+
+       bank = (struct s5p_gpio_bank *)i2c_gpio[bus_index].bus->gpio_base;
+
+       if (line)
+               line = i2c_gpio[bus_index].bus->sda_pin;
+       else
+               line = i2c_gpio[bus_index].bus->scl_pin;
+
+       gpio_set_value(bank, line, value);
+}
+
+int i2c_gpio_get(void)
+{
+       struct s5p_gpio_bank *bank;
+       unsigned int bus_index;
+
+       bus_index = i2c_get_bus_num();
+
+       bank = (struct s5p_gpio_bank *)i2c_gpio[bus_index].bus->gpio_base;
+
+       return gpio_get_value(bank, i2c_gpio[bus_index].bus->sda_pin);
+}
+
+void i2c_gpio_dir(int dir)
+{
+       struct s5p_gpio_bank *bank;
+       unsigned int bus_index;
+
+       bus_index = i2c_get_bus_num();
+
+       bank = (struct s5p_gpio_bank *)i2c_gpio[bus_index].bus->gpio_base;
+
+       if (dir) {
+               gpio_direction_output(bank,
+                               i2c_gpio[bus_index].bus->sda_pin, 0);
+       } else {
+               gpio_direction_input(bank,
+                               i2c_gpio[bus_index].bus->sda_pin);
+       }
+}
diff --git a/cpu/arm1176/s5p64xx/reset.S b/cpu/arm1176/s5p64xx/reset.S
new file mode 100644 (file)
index 0000000..002286f
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2009 Samsung Electronics.
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <asm/arch/cpu.h>
+
+#define S5P6442_SWRESET                        0xE0102000
+
+.globl reset_cpu
+reset_cpu:
+       ldr     r1, =S5P6442_SWRESET
+       mov     r2, #1
+       str     r2, [r1]
+_loop_forever:
+       b       _loop_forever
diff --git a/cpu/arm1176/s5p64xx/sleep.c b/cpu/arm1176/s5p64xx/sleep.c
new file mode 100644 (file)
index 0000000..47ec48b
--- /dev/null
@@ -0,0 +1,490 @@
+/*
+ * Sleep command for S5PC110
+ *
+ *  Copyright (C) 2005-2008 Samsung Electronics
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <i2c.h>
+#include <serial.h>
+#include <stdio_dev.h>
+#include <onenand_uboot.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/power.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
+#include "sleep.h"
+
+struct stack {
+       u32 irq[3];
+       u32 abt[3];
+       u32 und[3];
+} ____cacheline_aligned;
+
+static struct stack stacks[1];
+
+enum {
+       SLEEP_WFI,
+       SLEEP_REGISTER,
+};
+
+static void __board_sleep_init(void) { }
+
+void board_sleep_init(void)
+       __attribute__((weak, alias("__board_sleep_init")));
+
+struct regs_to_save {
+       unsigned int    start_address;
+       unsigned int    size;
+};
+
+static struct regs_to_save core_save[] = {
+       { .start_address = 0xE0100200, .size = 7 },
+       { .start_address = 0xE0100280, .size = 2 },
+       { .start_address = 0xE0100300, .size = 8 },
+       { .start_address = 0xE0100460, .size = 5 },
+       { .start_address = 0xE0100480, .size = 3 },
+       { .start_address = 0xE0100500, .size = 1 },
+       { .start_address = 0xE0107008, .size = 1 },
+       { .start_address = 0xE0103000, .size = 3 }, /* DCGIDC_MAP* */
+       { .start_address = 0xE0103020, .size = 2 }, /* DCGPREF_MAP* */
+       { .start_address = 0xE0103040, .size = 1 }, /* DVCIDX_MAP */
+       { .start_address = 0xE0103060, .size = 2 }, /* FREQ_CPU/DPM */
+       { .start_address = 0xE0103080, .size = 1 }, /* DVSEMCLK_EN */
+       { .start_address = 0xE0103084, .size = 1 }, /* MAXPERF */
+};
+
+static unsigned int buf_core_save[7 + 2 + 8 + 5 + 3 + 1 + 1 +
+                               3 + 2 + 1 + 2 + 1 + 1];
+
+static struct regs_to_save gpio_save[] = {
+       { .start_address = 0xE0200000, .size = 6 },
+       { .start_address = 0xE0200020, .size = 6 },
+       { .start_address = 0xE0200040, .size = 6 },
+       { .start_address = 0xE0200060, .size = 6 },
+       { .start_address = 0xE0200080, .size = 6 },
+       { .start_address = 0xE02000A0, .size = 6 },
+       { .start_address = 0xE02000C0, .size = 6 },
+       { .start_address = 0xE02000E0, .size = 6 },
+       { .start_address = 0xE0200100, .size = 6 },
+       { .start_address = 0xE0200120, .size = 6 },
+       { .start_address = 0xE0200140, .size = 6 },
+       { .start_address = 0xE0200160, .size = 6 },
+       { .start_address = 0xE0200180, .size = 6 },
+       { .start_address = 0xE02001A0, .size = 6 },
+       { .start_address = 0xE02001C0, .size = 6 },
+       { .start_address = 0xE02001E0, .size = 6 },
+       { .start_address = 0xE0200200, .size = 6 },
+       { .start_address = 0xE0200220, .size = 6 },
+       { .start_address = 0xE0200240, .size = 6 },
+       { .start_address = 0xE0200260, .size = 6 },
+       { .start_address = 0xE0200280, .size = 6 },
+       { .start_address = 0xE02002A0, .size = 6 },
+       { .start_address = 0xE02002C0, .size = 6 },
+       { .start_address = 0xE02002E0, .size = 6 },
+       { .start_address = 0xE0200300, .size = 6 },
+       { .start_address = 0xE0200320, .size = 6 },
+       { .start_address = 0xE0200340, .size = 6 },
+       { .start_address = 0xE0200360, .size = 6 },
+       { .start_address = 0xE0200380, .size = 6 },
+       { .start_address = 0xE02003A0, .size = 6 },
+       { .start_address = 0xE02003C0, .size = 6 },
+       { .start_address = 0xE02003E0, .size = 6 },
+       { .start_address = 0xE0200400, .size = 6 },
+       { .start_address = 0xE0200420, .size = 6 },
+       { .start_address = 0xE0200440, .size = 6 },
+       { .start_address = 0xE0200460, .size = 6 },
+       { .start_address = 0xE0200480, .size = 6 },
+       { .start_address = 0xE02004A0, .size = 6 },
+       { .start_address = 0xE02004C0, .size = 6 },
+       { .start_address = 0xE02004E0, .size = 6 },
+       { .start_address = 0xE0200500, .size = 6 },
+       { .start_address = 0xE0200520, .size = 6 },
+       { .start_address = 0xE0200540, .size = 6 },
+       { .start_address = 0xE0200560, .size = 6 },
+       { .start_address = 0xE0200580, .size = 6 },
+       { .start_address = 0xE02005A0, .size = 6 },
+       { .start_address = 0xE02005C0, .size = 6 },
+       { .start_address = 0xE02005E0, .size = 6 },
+       { .start_address = 0xE0200608, .size = 2 },
+       { .start_address = 0xE0200628, .size = 2 },
+       { .start_address = 0xE0200648, .size = 2 },
+       { .start_address = 0xE0200700, .size = 22 },
+       { .start_address = 0xE0200900, .size = 22 },
+       { .start_address = 0xE0200A00, .size = 22 },
+};
+
+static unsigned int buf_gpio_save[6 * 8 * 6 + 2 * 3 + 22 * 3];
+
+static struct regs_to_save irq_save[] = {
+       { .start_address = 0xF200000C, .size = 2 },
+       { .start_address = 0xF2000018, .size = 1 },
+       { .start_address = 0xF210000C, .size = 2 },
+       { .start_address = 0xF2100018, .size = 1 },
+       { .start_address = 0xF220000C, .size = 2 },
+       { .start_address = 0xF2200018, .size = 1 },
+       { .start_address = 0xF230000C, .size = 2 },
+       { .start_address = 0xF2300018, .size = 1 },
+};
+
+static unsigned int buf_irq_save[(2 + 1) * 4];
+
+static struct regs_to_save sromc_save[] = {
+       { .start_address = 0xE8000000, .size = 7 },
+};
+
+static unsigned int buf_sromc_save[7];
+
+static struct regs_to_save uart_save[] = {
+       { .start_address = 0xE2900000, .size = 4 },
+       { .start_address = 0xE2900028, .size = 2 },
+       { .start_address = 0xE2900038, .size = 1 },
+       { .start_address = 0xE2900400, .size = 4 },
+       { .start_address = 0xE2900428, .size = 2 },
+       { .start_address = 0xE2900438, .size = 1 },
+       { .start_address = 0xE2900800, .size = 4 },
+       { .start_address = 0xE2900828, .size = 2 },
+       { .start_address = 0xE2900838, .size = 1 },
+       { .start_address = 0xE2900C00, .size = 4 },
+       { .start_address = 0xE2900C28, .size = 2 },
+       { .start_address = 0xE2900C38, .size = 1 },
+};
+static unsigned int buf_uart_save[(4 + 2 + 1) * 4];
+
+static struct regs_to_save power_setting_save[] = {
+       { .start_address = S5PC110_OSC_CON, .size = 1}, /* OSC_CON */
+       { .start_address = S5PC110_PWR_CFG, .size = 5}, /* PWR_CFG ~ NORMAL_CFG */
+       { .start_address = S5PC110_IDLE_CFG, .size = 1},
+       { .start_address = S5PC110_STOP_CFG, .size = 2}, /* ~ STOP_MEM_CFG */
+       { .start_address = S5PC110_SLEEP_CFG, .size = 1},
+
+       { .start_address = S5PC110_OSC_FREQ, .size = 3}, /* ~ PWR_STABLE */
+       { .start_address = S5PC110_MTC_STABLE, .size = 2}, /* ~ CLAMP_STABLE */
+       { .start_address = S5PC110_OTHERS, .size = 1},
+       { .start_address = S5PC110_MIE_CONTROL, .size = 2}, /* ~ HDMI_CONTROL */
+       { .start_address = S5PC110_USB_PHY_CON, .size = 5}, /* ~ PS_HOLD_CONTROL */
+       { .start_address = S5PC110_INFORM0, .size = 8}, /* ~ INFORM7 */
+};
+static unsigned int buf_power_setting_save[1 + 5 + 1 + 2 + 1 +
+                                       3 + 2 + 1 + 2 + 5 + 8];
+
+static struct regs_to_save clock_setting_save[] = {
+       { .start_address = S5PC110_APLL_LOCK, .size = 1},
+       { .start_address = S5PC110_MPLL_LOCK, .size = 1},
+       { .start_address = S5PC110_EPLL_LOCK, .size = 1},
+       { .start_address = S5PC110_VPLL_LOCK, .size = 1},
+       { .start_address = S5PC110_APLL_CON, .size = 1},
+       { .start_address = S5PC110_MPLL_CON, .size = 1},
+       { .start_address = S5PC110_EPLL_CON, .size = 1},
+       { .start_address = S5PC110_VPLL_CON, .size = 1},
+};
+static unsigned int buf_clock_setting_save[8];
+
+static unsigned int reg_others;
+
+void s5pc110_save_reg(struct regs_to_save *list,
+               unsigned int *buf, int length)
+{
+       int i;
+       int j;
+       int counter = 0;
+
+       for (i = 0; i < length; i++) {
+               for (j = 0; j < list[i].size; j++) {
+                       *buf = readl((unsigned int *)
+                                       (list[i].start_address+j * 4));
+                       buf++;
+                       counter++;
+               }
+       }
+}
+
+void s5pc110_save_regs(void)
+{
+       reg_others = readl(S5PC110_OTHERS);
+       s5pc110_save_reg(gpio_save, buf_gpio_save, ARRAY_SIZE(gpio_save));
+       s5pc110_save_reg(irq_save, buf_irq_save, ARRAY_SIZE(irq_save));
+       s5pc110_save_reg(core_save, buf_core_save, ARRAY_SIZE(core_save));
+       s5pc110_save_reg(sromc_save, buf_sromc_save, ARRAY_SIZE(sromc_save));
+       s5pc110_save_reg(uart_save, buf_uart_save, ARRAY_SIZE(uart_save));
+
+       s5pc110_save_reg(power_setting_save, buf_power_setting_save,
+                       ARRAY_SIZE(power_setting_save));
+       s5pc110_save_reg(clock_setting_save, buf_clock_setting_save,
+                       ARRAY_SIZE(clock_setting_save));
+}
+
+void s5pc110_restore_reg(struct regs_to_save *list,
+               unsigned int *buf, int length)
+{
+       int i;
+       int j;
+
+       for (i = 0; i < length; i++) {
+               for (j = 0; j < list[i].size; j++) {
+                       writel(*buf, (unsigned int *)
+                                       (list[i].start_address+j * 4));
+
+                       if (s5pc1xx_get_cpu_rev() == 0) {
+                               unsigned int tmp;
+                               tmp = readl((unsigned int *)
+                                               (list[i].start_address+j * 4));
+                       }
+
+                       buf++;
+               }
+       }
+
+}
+
+void s5pc110_restore_regs(void)
+{
+       s5pc110_restore_reg(uart_save, buf_uart_save, ARRAY_SIZE(uart_save));
+       s5pc110_restore_reg(sromc_save, buf_sromc_save, ARRAY_SIZE(sromc_save));
+       s5pc110_restore_reg(core_save, buf_core_save, ARRAY_SIZE(core_save));
+       s5pc110_restore_reg(irq_save, buf_irq_save, ARRAY_SIZE(irq_save));
+       s5pc110_restore_reg(gpio_save, buf_gpio_save, ARRAY_SIZE(gpio_save));
+
+       s5pc110_restore_reg(power_setting_save, buf_power_setting_save,
+                       ARRAY_SIZE(power_setting_save));
+       s5pc110_restore_reg(clock_setting_save, buf_clock_setting_save,
+                       ARRAY_SIZE(clock_setting_save));
+}
+
+void s5pc110_wakeup(void)
+{
+       struct stack *stk = &stacks[0];
+       __asm__ (
+                       "msr    cpsr_c, %1\n\t"
+                       "add    sp, %0, %2\n\t"
+                       "msr    cpsr_c, %3\n\t"
+                       "add    sp, %0, %4\n\t"
+                       "msr    cpsr_c, %5\n\t"
+                       "add    sp, %0, %6\n\t"
+                       "msr    cpsr_c, %7"
+                       :
+                       : "r" (stk),
+                       "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
+                       "I" (offsetof(struct stack, irq[0])),
+                       "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
+                       "I" (offsetof(struct stack, abt[0])),
+                       "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
+                       "I" (offsetof(struct stack, und[0])),
+                       "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
+                       : "r14");
+
+       s5pc110_restore_regs();
+
+       reg_others |= (1 << 31); /* GPIO */
+       reg_others |= (1 << 30); /* CF I/O */
+       reg_others |= (1 << 29); /* MMC */
+       reg_others |= (1 << 28); /* UART */
+       writel(reg_others, S5PC110_OTHERS);
+
+       printf("%s: Waking up...\n", __func__);
+
+       timer_init();
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+       /* init_func_i2c */
+       i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
+#if defined(CONFIG_CMD_ONENAND)
+       onenand_init();
+#endif
+#ifdef CONFIG_SERIAL_MULTI
+       serial_initialize();
+#endif
+       stdio_init_resume();   /* get the devices list going. */
+
+       return;
+}
+
+static int s5pc110_sleep(int mode)
+{
+       unsigned long regs_save[16];
+       unsigned int value;
+       int i;
+
+       printf("Entering s5pc110_sleep();\n");
+
+       board_sleep_init();
+
+       value = readl(S5PC110_WAKEUP_MASK);
+       value |= (1 << 15);
+       value |= (1 << 14);
+       value |= (1 << 13);
+       value |= (1 << 12);
+       value |= (1 << 11);
+       value |= (1 << 10);
+       value |= (1 << 9);
+       value |= (1 << 5);
+       value |= (1 << 4);
+       value |= (1 << 3);
+       value |= (1 << 2);
+       value |= (1 << 1);
+
+       writel(value, S5PC110_WAKEUP_MASK);
+
+       value = readl(S5PC110_EINT_WAKEUP_MASK);
+       value = 0xFFFFFFFF;
+       value &= ~(1 << 7);       /* AP_PMIC_IRQ */
+       value &= ~(1 << 22);      /* nPOWER */
+       /*      value &= ~(1 << 23);*/    /* JACK_nINT */
+       value &= ~(1 << 24);      /* KBR(0) */
+       value &= ~(1 << 25);      /* KBR(1) */
+       /*      value &= ~(1 << 28);*/    /* T-Flash */
+       writel(value, S5PC110_EINT_WAKEUP_MASK);
+
+       if (s5pc1xx_get_cpu_rev() == 0) {
+               value = readl(S5PC110_EINT_WAKEUP_MASK);
+               for (i = 0; i < 4; i++)
+                       value = readl(0xE0200F40 + i * 4);
+       }
+
+       s5pc110_save_regs();
+
+       board_sleep_init_late();
+
+       writel((unsigned long) s5pc110_cpu_resume, S5PC110_INFORM0);
+
+       if (s5pc1xx_get_cpu_rev() == 0) {
+               value = readl(S5PC110_SLEEP_CFG);
+               value &= ~(1 << 0); /* OSC_EN off */
+               value &= ~(1 << 1); /* USBOSC_EN off */
+               writel(value, S5PC110_SLEEP_CFG);
+       }
+
+       value = readl(S5PC110_PWR_CFG);
+       value &= ~S5PC110_CFG_STANDBYWFI_MASK;
+       if (mode == SLEEP_WFI) {
+               if (s5pc1xx_get_cpu_rev() == 0) {
+                       printf("ERRATA MODE\n");
+                       value |= S5PC110_CFG_STANDBYWFI_IGNORE;
+               } else {
+                       value |= S5PC110_CFG_STANDBYWFI_SLEEP;
+               }
+       } else {
+               value |= S5PC110_CFG_STANDBYWFI_IGNORE;
+       }
+
+       writel(value, S5PC110_PWR_CFG);
+
+       /* F2000000: VICIRQSTATUS-irq0 */
+       writel(0xffffffff, 0xF2000000 + 0x14); /* VIC_INT_ENABLE_CLEAR */
+       writel(0xffffffff, 0xF2100000 + 0x14);
+       writel(0xffffffff, 0xF2200000 + 0x14);
+       writel(0xffffffff, 0xF2300000 + 0x14);
+       writel(0xffffffff, 0xF2000000 + 0x1c); /* VIC_INT_SOFT_CLEAR */
+       writel(0xffffffff, 0xF2100000 + 0x1c);
+       writel(0xffffffff, 0xF2200000 + 0x1c);
+       writel(0xffffffff, 0xF2300000 + 0x1c);
+
+       /* Clear all EINT PENDING bit */
+       writel(0xff, 0xE0200000 + 0xF40);
+       value = readl(0xE0200000 + 0xF40);
+       writel(0xff, 0xE0200000 + 0xF44);
+       value = readl(0xE0200000 + 0xF44);
+       writel(0xff, 0xE0200000 + 0xF48);
+       value = readl(0xE0200000 + 0xF48);
+       writel(0xff, 0xE0200000 + 0xF4C);
+       value = readl(0xE0200000 + 0xF4C);
+
+       value = readl(S5PC110_WAKEUP_STAT);
+       writel(value, S5PC110_WAKEUP_STAT);
+
+
+       value = readl(S5PC110_OTHERS);
+       value |= S5PC110_OTHERS_SYSCON_INT_DISABLE;
+       writel(value, S5PC110_OTHERS);
+
+       s5pc110_sleep_save_phys = (unsigned int) regs_save;
+
+       value = readl(S5PC110_OTHERS);
+       value |= 1;
+       writel(value, S5PC110_OTHERS);
+
+       /* cache flush */
+       asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
+       l2_cache_disable();
+       invalidate_dcache(get_device_type());
+
+       if (s5pc110_cpu_save(regs_save) == 0) {
+               /* cache flush */
+               asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
+               l2_cache_disable();
+               invalidate_dcache(get_device_type());
+
+               if (mode == SLEEP_WFI) {
+                       if (s5pc1xx_get_cpu_rev() == 0) {
+                               printf("Warn: Entering SLEEP_WFI mode with"
+                                       "EVT0_ERRATA. \n");
+                               printf("Warn: This sleep will probably fail\n");
+                       }
+
+                       value = readl(S5PC110_PWR_CFG);
+                       value &= ~S5PC110_CFG_STANDBYWFI_MASK;
+                       value |= S5PC110_CFG_STANDBYWFI_SLEEP;
+                       writel(value, S5PC110_PWR_CFG);
+
+                       asm ("b 1f\n\t"
+                               ".align 5\n\t"
+                               "1:\n\t"
+                               "mcr p15, 0, %0, c7, c10, 5\n\t"
+                               "mcr p15, 0, %0, c7, c10, 4\n\t"
+                               ".word 0xe320f003" :: "r" (value));
+
+               } else { /* SLEEP_REGISTER */
+                       value = (1 << 2);
+                       writel(value, S5PC110_PWR_MODE);
+
+                       while (1)
+                               ;
+               }
+       }
+
+
+       s5pc110_wakeup();
+
+       writel(0, S5PC110_EINT_WAKEUP_MASK);
+       readl(S5PC110_EINT_WAKEUP_MASK);
+
+       for (i = 0; i < 4; i++)
+               readl(0xE0200F40 + i * 4);
+
+       value = readl(S5PC110_WAKEUP_STAT);
+       writel(0xFFFF & value, S5PC110_WAKEUP_STAT);
+
+       printf("Wakeup Source: 0x%08x\n", value);
+       value = readl(S5PC110_WAKEUP_STAT);
+
+       board_sleep_resume();
+       return 0;
+}
+
+int do_sleep(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       int mode = SLEEP_WFI;
+
+       if (argc >= 2)
+               mode = SLEEP_REGISTER;
+
+       if (cpu_is_s5pc110())
+               return s5pc110_sleep(mode);
+
+       cmd_usage(cmdtp);
+       return 1;
+}
+
+U_BOOT_CMD(
+       sleep,          CONFIG_SYS_MAXARGS,     1, do_sleep,
+       "S5PC110 sleep",
+       "- Sleep with SLEEP_WFI mode\n"
+       "sleep 1 - Sleep with SLEEP_REGISTER mode\n"
+);
diff --git a/cpu/arm1176/s5p64xx/sleep.h b/cpu/arm1176/s5p64xx/sleep.h
new file mode 100644 (file)
index 0000000..ce8cb1a
--- /dev/null
@@ -0,0 +1,67 @@
+/* 
+ * Copied and modified from linux/arch/arm/plat-s5pc11x/pm.c
+ * Copyright (c) 2004,2009 Simtec Electronics
+ *     boyko.lee <boyko.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Parts based on arch/arm/mach-pxa/pm.c
+ *
+ * Thanks to Dimitry Andric for debugging
+*/
+
+#ifndef __S5PC110_SLEEP_H
+#define __S5PC110_SLEEP_H
+
+#include <common.h>
+#include <asm/ptrace.h>
+
+/*
+ * PSR bits
+ */
+/* #define USR26_MODE      0x00000000 */
+/* #define FIQ26_MODE      0x00000001 */
+/* #define IRQ26_MODE      0x00000002 */
+/* #define SVC26_MODE      0x00000003 */
+/* #define USR_MODE        0x00000010 */
+/* #define FIQ_MODE        0x00000011 */
+/* #define IRQ_MODE        0x00000012 */
+/* #define SVC_MODE        0x00000013 */
+/* #define ABT_MODE        0x00000017 */
+/* #define UND_MODE        0x0000001b */
+/* #define SYSTEM_MODE     0x0000001f */
+#define MODE32_BIT      0x00000010
+/* #define MODE_MASK       0x0000001f */
+#define PSR_T_BIT       0x00000020
+#define PSR_F_BIT       0x00000040
+#define PSR_I_BIT       0x00000080
+#define PSR_A_BIT       0x00000100
+#define PSR_J_BIT       0x01000000
+#define PSR_Q_BIT       0x08000000
+#define PSR_V_BIT       0x10000000
+#define PSR_C_BIT       0x20000000
+#define PSR_Z_BIT       0x40000000
+#define PSR_N_BIT       0x80000000
+
+#ifndef __ASSEMBLY__
+extern void board_sleep_resume(void);
+extern int s5pc110_cpu_save(unsigned long *saveblk);
+extern void s5pc110_cpu_resume(void);
+extern unsigned int s5pc110_sleep_return_addr;
+extern unsigned int s5pc110_sleep_save_phys;
+
+#endif
+
+#endif
diff --git a/cpu/arm1176/s5p64xx/sleep_asm.S b/cpu/arm1176/s5p64xx/sleep_asm.S
new file mode 100644 (file)
index 0000000..a29c48d
--- /dev/null
@@ -0,0 +1,160 @@
+/* linux/arch/arm/plat-s3c64xx/sleep.S
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6410 Power Manager (Suspend-To-RAM) support
+ *
+ * Based on PXA/SA1100 sleep code by:
+ *     Nicolas Pitre, (c) 2002 Monta Vista Software Inc
+ *     Cliff Brake, (c) 2001
+ *
+ * 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/assembler.h>
+#include <asm/ptrace.h>
+#define ENTRY(name)                            \
+       .global name;                           \
+       .align 4,0x90;                          \
+name:
+
+#include "sleep.h"
+#define SWRESET_VALUE  0xE0102000
+
+/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
+ * reset the UART configuration, only enable if you really need this!
+*/
+       .text
+
+       /* s5pc110_cpu_save
+        *
+        * save enough of the CPU state to allow us to re-start
+        * pm.c code. as we store items like the sp/lr, we will
+        * end up returning from this function when the cpu resumes
+        * so the return value is set to mark this.
+        *
+        * This arangement means we avoid having to flush the cache
+        * from this code.
+        *
+        * entry:
+        *      r0 = pointer to save block
+        *
+        * exit:
+        *      r0 = 0 => we stored everything
+        *           1 => resumed from sleep
+       */
+
+ENTRY(s5pc110_cpu_save)
+
+       stmfd   sp!, { r3 - r12, lr }
+
+       mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
+       mrc     p15, 0, r5, c3, c0, 0   @ Domain ID
+       mrc     p15, 0, r6, c2, c0, 0   @ Translation Table BASE0
+       mrc     p15, 0, r7, c2, c0, 1   @ Translation Table BASE1
+       mrc     p15, 0, r8, c2, c0, 2   @ Translation Table Control
+       mrc     p15, 0, r9, c1, c0, 0   @ Control register
+       mrc     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
+       mrc     p15, 0, r11, c1, c0, 2  @ Co-processor access controls
+       mrc     p15, 0, r12, c10, c2, 0 @ Read PRRR
+       mrc     p15, 0, r3, c10, c2, 1  @ READ NMRR     
+
+       stmia   r0, { r3 - r13 }
+
+       mov     r0, #0
+       ldmfd   sp, { r3 - r12, pc }
+
+       @@ return to the caller, after having the MMU
+       @@ turned on, this restores the last bits from the
+       @@ stack
+       .align  4
+resume_without_mmu:
+       mov     r0, #1
+
+       ldmfd   sp!, { r3 - r12, pc }
+
+       .ltorg
+
+       @@ the next bits sit in the .data segment, even though they
+       @@ happen to be code... the s5pc110_sleep_save_phys needs to be
+       @@ accessed by the resume code before it can restore the MMU.
+       @@ This means that the variable has to be close enough for the
+       @@ code to read it... since the .text segment needs to be RO,
+       @@ the data segment can be the only place to put this code.
+
+       .data
+
+
+
+       .global s5pc110_sleep_save_phys
+s5pc110_sleep_save_phys:
+       .word   0
+
+
+       /* sleep magic, to allow the bootloader to check for an valid
+        * image to resume to. Must be the first word before the
+        * s5pc110_cpu_resume entry.
+       */
+
+       .word   0x2bedf00d
+
+       /* s5pc110_cpu_resume
+        *
+        * resume code entry for bootloader to call
+        *
+        * we must put this code here in the data segment as we have no
+        * other way of restoring the stack pointer after sleep, and we
+        * must not write to the code segment (code is read-only)
+       */
+
+ENTRY(s5pc110_cpu_resume)
+       mov     r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+       msr     cpsr_c, r0
+
+       @@ load UART to allow us to print the two characters for
+       @@ resume debug
+
+       mov     r1, #0
+       mcr     p15, 0, r1, c8, c7, 0           @@ invalidate TLBs
+       mcr     p15, 0, r1, c7, c5, 0           @@ invalidate I Cache
+
+       ldr     r0, s5pc110_sleep_save_phys     @ address of restore block
+       ldmia   r0, { r3 - r13 }
+
+       mcr     p15, 0, r4, c13, c0, 0  @ FCSE/PID
+       mcr     p15, 0, r5, c3, c0, 0   @ Domain ID
+       
+       mcr     p15, 0, r8, c2, c0, 2   @ Translation Table Control
+       mcr     p15, 0, r7, c2, c0, 1   @ Translation Table BASE1
+       mcr     p15, 0, r6, c2, c0, 0   @ Translation Table BASE0
+
+       mcr     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
+
+       mov     r0, #0
+       mcr     p15, 0, r0, c8, c7, 0   @ Invalidate I & D TLB
+
+       mov     r0, #0                  @ restore copro access controls
+       mcr     p15, 0, r11, c1, c0, 2  @ Co-processor access controls
+       mcr     p15, 0, r0, c7, c5, 4   
+
+       mcr     p15, 0, r12, c10, c2, 0 @ write PRRR
+       mcr     p15, 0, r3, c10, c2, 1  @ write NMRR
+
+       ldr     r2, =resume_without_mmu
+       mov     pc, r2
+
+       .ltorg
+
diff --git a/cpu/arm1176/s5p64xx/timer.c b/cpu/arm1176/s5p64xx/timer.c
new file mode 100644 (file)
index 0000000..a99af78
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Heungjun Kim <riverful.kim@samsung.com>
+ * Inki Dae <inki.dae@samsung.com>
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/pwm.h>
+#include <asm/arch/clk.h>
+
+#define PRESCALER_1            (16 - 1)        /* prescaler of timer 2, 3, 4 */
+#define MUX_DIV_2              1               /* 1/2 period */
+#define MUX_DIV_4              2               /* 1/4 period */
+#define MUX_DIV_8              3               /* 1/8 period */
+#define MUX_DIV_16             4               /* 1/16 period */
+#define MUX4_DIV_SHIFT         16
+
+#define TCON_TIMER4_SHIFT      20
+
+static unsigned long count_value;
+
+/* Internal tick units */
+static unsigned long long timestamp;   /* Monotonic incrementing timer */
+static unsigned long lastdec;          /* Last decremneter snapshot */
+
+/* macro to read the 16 bit timer */
+static inline struct s5p64xx_timer *s5p64xx_get_base_timer(void)
+{
+       if (cpu_is_s5p6442())
+               return (struct s5p64xx_timer *)S5P6442_TIMER_BASE;
+       else
+               return NULL;
+}
+
+int timer_init(void)
+{
+       struct s5p64xx_timer *const timer = s5p64xx_get_base_timer();
+       u32 val;
+
+       /*
+        * @ PWM Timer 4
+        * Timer Freq(HZ) =
+        *      PCLK / { (prescaler_value + 1) * (divider_value) }
+        */
+
+       /* set prescaler : 16 */
+       /* set divider : 2 */
+       val = readl(&timer->tcfg0);
+       val &= ~(0xff << 8);
+       val |= (PRESCALER_1 & 0xff) << 8;
+       writel(val, &timer->tcfg0);
+       val = readl(&timer->tcfg1);
+       val &= ~(0xf << MUX4_DIV_SHIFT);
+       val |= (MUX_DIV_2 & 0xF) << MUX4_DIV_SHIFT;
+       writel(val, &timer->tcfg1);
+
+       if (count_value == 0) {
+               /* reset initial value */
+               /* count_value = 2085937.5(HZ) (per 1 sec)*/
+               count_value = get_pclk() / ((PRESCALER_1 + 1) *
+                               (MUX_DIV_2 + 1));
+
+               /* count_value / 100 = 20859.375(HZ) (per 10 msec) */
+               count_value = count_value / 100;
+       }
+
+       /* set count value */
+       writel(count_value, &timer->tcntb4);
+       lastdec = count_value;
+
+       val = (readl(&timer->tcon) & ~(0x07 << TCON_TIMER4_SHIFT)) |
+               S5P64XX_TCON4_AUTO_RELOAD;
+
+       /* auto reload & manual update */
+       writel(val | S5P64XX_TCON4_UPDATE, &timer->tcon);
+
+       /* start PWM timer 4 */
+       writel(val | S5P64XX_TCON4_START, &timer->tcon);
+
+       timestamp = 0;
+
+       return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+void reset_timer(void)
+{
+       reset_timer_masked();
+}
+
+unsigned long get_timer(unsigned long base)
+{
+       return get_timer_masked() - base;
+}
+
+void set_timer(unsigned long t)
+{
+       timestamp = t;
+}
+
+/* delay x useconds */
+void udelay(unsigned long usec)
+{
+       unsigned long tmo, tmp, now, until;
+
+       if (usec >= 1000) {
+               /*
+                * if "big" number, spread normalization
+                * to seconds
+                * 1. start to normalize for usec to ticks per sec
+                * 2. find number of "ticks" to wait to achieve target
+                * 3. finish normalize.
+                */
+               tmo = usec / 1000;
+               tmo *= (CONFIG_SYS_HZ * count_value / 10);
+               tmo /= 1000;
+       } else {
+               /* else small number, don't kill it prior to HZ multiply */
+               tmo = usec * CONFIG_SYS_HZ * count_value / 10;
+               tmo /= (1000 * 1000);
+       }
+
+       /* get current timestamp */
+       tmp = get_timer_masked();
+
+       /* if setting this fordward will roll time stamp */
+       /* reset "advancing" timestamp to 0, set lastdec value */
+       /* else, set advancing stamp wake up time */
+       until = tmo + tmp + count_value;
+       if (until < tmp) {
+               reset_timer_masked();
+               tmp = get_timer_masked();
+               tmo += tmp;
+
+       }
+       else
+               tmo += tmp;
+
+       /* loop till event */ /* FIX: consider the overflow case */
+       while ((now = get_timer_masked()) < tmo && now >= tmp)
+               ;       /* nop */
+}
+
+void reset_timer_masked(void)
+{
+       struct s5p64xx_timer *const timer = s5p64xx_get_base_timer();
+
+       /* reset time */
+       lastdec = readl(&timer->tcnto4);
+       timestamp = 0;
+}
+
+unsigned long get_timer_masked(void)
+{
+       struct s5p64xx_timer *const timer = s5p64xx_get_base_timer();
+       unsigned long now = readl(&timer->tcnto4);
+
+       if (lastdec >= now)
+               timestamp += lastdec - now;
+       else
+               timestamp += lastdec + count_value - now;
+
+       lastdec = now;
+
+       return timestamp;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+       return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+unsigned long get_tbclk(void)
+{
+       return CONFIG_SYS_HZ;
+}
diff --git a/cpu/arm1176/s5p64xx/usb-hs-otg.c b/cpu/arm1176/s5p64xx/usb-hs-otg.c
new file mode 100644 (file)
index 0000000..7851b2d
--- /dev/null
@@ -0,0 +1,1816 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#include <command.h>
+#include <asm/errno.h>
+#include <asm/arch/power.h>
+#include "usb-hs-otg.h"
+
+#define SUSPEND_RESUME_ON 0
+
+u32 remode_wakeup;
+u16 config_value;
+
+int s5p_receive_done;
+int s5p_got_header;
+int s5p_usb_connected;
+
+USB_OPMODE op_mode = USB_CPU;
+USB_SPEED speed = USB_HIGH;
+/*
+USB_OPMODE op_mode = USB_DMA;
+USB_SPEED speed = USB_FULL;
+*/
+
+otg_dev_t otg;
+get_status_t get_status;
+get_intf_t get_intf;
+
+enum EP_INDEX {
+       EP0, EP1, EP2, EP3, EP4
+};
+
+/*------------------------------------------------*/
+/* EP0 state */
+enum EP0_STATE {
+       EP0_STATE_INIT = 0,
+       EP0_STATE_GD_DEV_0 = 11,
+       EP0_STATE_GD_DEV_1 = 12,
+       EP0_STATE_GD_DEV_2 = 13,
+       EP0_STATE_GD_CFG_0 = 21,
+       EP0_STATE_GD_CFG_1 = 22,
+       EP0_STATE_GD_CFG_2 = 23,
+       EP0_STATE_GD_CFG_3 = 24,
+       EP0_STATE_GD_CFG_4 = 25,
+       EP0_STATE_GD_STR_I0 = 30,
+       EP0_STATE_GD_STR_I1 = 31,
+       EP0_STATE_GD_STR_I2 = 32,
+       EP0_STATE_GD_DEV_QUALIFIER = 33,
+       EP0_STATE_INTERFACE_GET = 34,
+       EP0_STATE_GET_STATUS0 = 35,
+       EP0_STATE_GET_STATUS1 = 36,
+       EP0_STATE_GET_STATUS2 = 37,
+       EP0_STATE_GET_STATUS3 = 38,
+       EP0_STATE_GET_STATUS4 = 39,
+       EP0_STATE_GD_OTHER_SPEED = 40,
+       EP0_STATE_GD_CFG_ONLY_0 = 41,
+       EP0_STATE_GD_CFG_ONLY_1 = 42,
+       EP0_STATE_GD_IF_ONLY_0 = 44,
+       EP0_STATE_GD_IF_ONLY_1 = 45,
+       EP0_STATE_GD_EP0_ONLY_0 = 46,
+       EP0_STATE_GD_EP1_ONLY_0 = 47,
+       EP0_STATE_GD_EP2_ONLY_0 = 48,
+       EP0_STATE_GD_EP3_ONLY_0 = 49,
+       EP0_STATE_GD_OTHER_SPEED_HIGH_1 = 51,
+       EP0_STATE_GD_OTHER_SPEED_HIGH_2 = 52,
+       EP0_STATE_GD_OTHER_SPEED_HIGH_3 = 53
+};
+
+/*definitions related to CSR setting */
+
+/* OTG_GOTGCTL*/
+#define B_SESSION_VALID                (0x1 << 19)
+#define A_SESSION_VALID                (0x1 << 18)
+
+/* OTG_GAHBCFG*/
+#define PTXFE_HALF             (0<<8)
+#define PTXFE_ZERO             (1<<8)
+#define NPTXFE_HALF            (0<<7)
+#define NPTXFE_ZERO            (1<<7)
+#define MODE_SLAVE             (0<<5)
+#define MODE_DMA               (1<<5)
+#define BURST_SINGLE           (0<<1)
+#define BURST_INCR             (1<<1)
+#define BURST_INCR4            (3<<1)
+#define BURST_INCR8            (5<<1)
+#define BURST_INCR16           (7<<1)
+#define GBL_INT_UNMASK         (1<<0)
+#define GBL_INT_MASK           (0<<0)
+
+/* OTG_GRSTCTL*/
+#define AHB_MASTER_IDLE                (1u<<31)
+#define CORE_SOFT_RESET                (0x1<<0)
+
+/* OTG_GINTSTS/OTG_GINTMSK core interrupt register */
+#define INT_RESUME             (1u<<31)
+#define INT_DISCONN            (0x1<<29)
+#define INT_CONN_ID_STS_CNG    (0x1<<28)
+#define INT_OUT_EP             (0x1<<19)
+#define INT_IN_EP              (0x1<<18)
+#define INT_ENUMDONE           (0x1<<13)
+#define INT_RESET              (0x1<<12)
+#define INT_SUSPEND            (0x1<<11)
+#define INT_TX_FIFO_EMPTY      (0x1<<5)
+#define INT_RX_FIFO_NOT_EMPTY  (0x1<<4)
+#define INT_SOF                        (0x1<<3)
+#define INT_DEV_MODE           (0x0<<0)
+#define INT_HOST_MODE          (0x1<<1)
+#define INT_OTG                        (0x1<<2)
+
+/* OTG_GRXSTSP STATUS*/
+#define GLOBAL_OUT_NAK                 (0x1<<17)
+#define OUT_PKT_RECEIVED               (0x2<<17)
+#define OUT_TRNASFER_COMPLETED         (0x3<<17)
+#define SETUP_TRANSACTION_COMPLETED    (0x4<<17)
+#define SETUP_PKT_RECEIVED             (0x6<<17)
+
+/* OTG_DCTL device control register */
+#define NORMAL_OPERATION               (0x1<<0)
+#define SOFT_DISCONNECT                        (0x1<<1)
+#define        TEST_J_MODE                     (TEST_J<<4)
+#define        TEST_K_MODE                     (TEST_K<<4)
+#define        TEST_SE0_NAK_MODE               (TEST_SE0_NAK<<4)
+#define        TEST_PACKET_MODE                (TEST_PACKET<<4)
+#define        TEST_FORCE_ENABLE_MODE          (TEST_FORCE_ENABLE<<4)
+#define TEST_CONTROL_FIELD             (0x7<<4)
+
+/* OTG_DAINT device all endpoint interrupt register */
+#define INT_IN_EP0                     (0x1<<0)
+#define INT_IN_EP1                     (0x1<<1)
+#define INT_IN_EP3                     (0x1<<3)
+#define INT_OUT_EP0                    (0x1<<16)
+#define INT_OUT_EP2                    (0x1<<18)
+#define INT_OUT_EP4                    (0x1<<20)
+
+/* OTG_DIEPCTL0/OTG_DOEPCTL0 */
+#define DEPCTL_EPENA                   (0x1<<31)
+#define DEPCTL_EPDIS                   (0x1<<30)
+#define DEPCTL_SNAK                    (0x1<<27)
+#define DEPCTL_CNAK                    (0x1<<26)
+#define DEPCTL_CTRL_TYPE               (EP_TYPE_CONTROL<<18)
+#define DEPCTL_ISO_TYPE                        (EP_TYPE_ISOCHRONOUS<<18)
+#define DEPCTL_BULK_TYPE               (EP_TYPE_BULK<<18)
+#define DEPCTL_INTR_TYPE               (EP_TYPE_INTERRUPT<<18)
+#define DEPCTL_USBACTEP                        (0x1<<15)
+
+/*ep0 enable, clear nak, next ep0, max 64byte */
+#define EPEN_CNAK_EP0_64 (DEPCTL_EPENA|DEPCTL_CNAK|(CONTROL_EP<<11)|(0<<0))
+
+/*ep0 enable, clear nak, next ep0, 8byte */
+#define EPEN_CNAK_EP0_8 (DEPCTL_EPENA|DEPCTL_CNAK|(CONTROL_EP<<11)|(3<<0))
+
+/* DIEPCTLn/DOEPCTLn */
+#define BACK2BACK_SETUP_RECEIVED       (0x1<<6)
+#define INTKN_TXFEMP                   (0x1<<4)
+#define NON_ISO_IN_EP_TIMEOUT          (0x1<<3)
+#define CTRL_OUT_EP_SETUP_PHASE_DONE   (0x1<<3)
+#define AHB_ERROR                      (0x1<<2)
+#define TRANSFER_DONE                  (0x1<<0)
+
+/* codes representing languages */
+const u8 string_desc0[] = {
+       4, STRING_DESCRIPTOR, LANGID_US_L, LANGID_US_H,
+};
+
+#ifdef CONFIG_SAMSUNG_USB
+const u8 string_desc1[] =      /* Manufacturer */
+{
+       (0x14 + 2), STRING_DESCRIPTOR,
+       'S', 0x0, '/', 0x0, 'W', 0x0, ' ', 0x0, 'C', 0x0,
+       'e', 0x0, 'n', 0x0, 't', 0x0, 'e', 0x0, 'r', 0x0,
+};
+#else
+const u8 string_desc1[] =      /* Manufacturer */
+{
+       (0x14 + 2), STRING_DESCRIPTOR,
+       'S', 0x0, 'y', 0x0, 's', 0x0, 't', 0x0, 'e', 0x0,
+       'm', 0x0, ' ', 0x0, 'M', 0x0, 'C', 0x0, 'U', 0x0,
+};
+#endif
+
+#ifdef CONFIG_SAMSUNG_USB
+const u8 string_desc2[] =      /* Product */
+{
+       (0x22 + 2), STRING_DESCRIPTOR,
+       'S', 0x0, 'A', 0x0, 'M', 0x0, 'S', 0x0, 'U', 0x0,
+       'N', 0x0, 'G', 0x0, ' ', 0x0, 'X', 0x0, 'O', 0x0,
+       ' ', 0x0, 'D', 0x0, 'R', 0x0, 'I', 0x0, 'V', 0x0,
+       'E', 0x0, 'R', 0x0
+};
+#else
+const u8 string_desc2[] =      /* Product */
+{
+       (0x2a + 2), STRING_DESCRIPTOR,
+       'S', 0x0, 'E', 0x0, 'C', 0x0, ' ', 0x0, 'S', 0x0,
+       '3', 0x0, 'C', 0x0, '6', 0x0, '4', 0x0, '0', 0x0,
+       '0', 0x0, 'X', 0x0, ' ', 0x0, 'T', 0x0, 'e', 0x0,
+       's', 0x0, 't', 0x0, ' ', 0x0, 'B', 0x0, '/', 0x0,
+       'D', 0x0
+};
+#endif
+
+/* setting the device qualifier descriptor and a string descriptor */
+const u8 qualifier_desc[] = {
+       0x0a,           /*  0 desc size */
+       0x06,           /*  1 desc type (DEVICE_QUALIFIER) */
+       0x00,           /*  2 USB release */
+       0x02,           /*  3 => 2.00 */
+       0xFF,           /*  4 class */
+       0x00,           /*  5 subclass */
+       0x00,           /*  6 protocol */
+       64,             /*  7 max pack size */
+       0x01,           /*  8 number of other-speed configuration */
+       0x00,           /*  9 reserved */
+};
+
+const u8 config_full[] = {
+       0x09,           /*  0 desc size */
+       0x07,           /*  1 desc type (other speed) */
+       0x20,           /*  2 Total length of data returned */
+       0x00,           /*  3 */
+       0x01,           /*  4 Number of interfaces */
+       0x01,           /*  5 value to use to select configuration */
+       0x00,           /*  6 index of string desc */
+       /*  7 same as configuration desc */
+       CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED,
+       0x19,           /*  8 same as configuration desc */
+
+};
+
+const u8 config_full_total[] = {
+       0x09, 0x07, 0x20, 0x00, 0x01, 0x01, 0x00, 0xC0, 0x19,
+       0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0x00, 0x00, 0x00,
+       0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00,
+       0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00
+};
+
+const u8 config_high[] = {
+       0x09,           /*  0 desc size */
+       0x07,           /*  1 desc type (other speed) */
+       0x20,           /*  2 Total length of data returned */
+       0x00,           /*  3 */
+       0x01,           /*  4 Number of interfaces */
+       0x01,           /*  5 value to use to select configuration */
+       0x00,           /*  6 index of string desc */
+       /*  7 same as configuration desc */
+       CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED,
+       0x19,                   /*  8 same as configuration desc */
+
+};
+
+const u8 config_high_total[] = {
+       0x09, 0x07, 0x20, 0x00, 0x01, 0x01, 0x00, 0xC0, 0x19,
+       0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0x00, 0x00, 0x00,
+       0x07, 0x05, 0x81, 0x02, 0x00, 0x02, 0x00,
+       0x07, 0x05, 0x02, 0x02, 0x00, 0x02, 0x00
+};
+
+/* Descriptor size */
+enum DESCRIPTOR_SIZE {
+       DEVICE_DESC_SIZE = sizeof(device_desc_t),
+       STRING_DESC0_SIZE = sizeof(string_desc0),
+       STRING_DESC1_SIZE = sizeof(string_desc1),
+       STRING_DESC2_SIZE = sizeof(string_desc2),
+       CONFIG_DESC_SIZE = sizeof(config_desc_t),
+       INTERFACE_DESC_SIZE = sizeof(intf_desc_t),
+       ENDPOINT_DESC_SIZE = sizeof(ep_desc_t),
+       DEVICE_QUALIFIER_SIZE = sizeof(qualifier_desc),
+       OTHER_SPEED_CFG_SIZE = 9
+};
+
+/*32 <cfg desc>+<if desc>+<endp0 desc>+<endp1 desc>*/
+#define CONFIG_DESC_TOTAL_SIZE \
+       (CONFIG_DESC_SIZE+INTERFACE_DESC_SIZE+ENDPOINT_DESC_SIZE*2)
+
+static unsigned int phy_base;
+static unsigned int otg_base;
+
+static inline void s5p_usb_init_base(void)
+{
+       if (cpu_is_s5pc110()) {
+               phy_base = S5PC110_PHY_BASE;
+               otg_base = S5PC110_OTG_BASE;
+       } else {
+               phy_base = S5PC100_PHY_BASE;
+               otg_base = S5PC100_OTG_BASE;
+       }
+}
+
+static inline int s5pc1xx_phy_read_reg(int offset)
+{
+       return readl(phy_base + offset);
+}
+
+static inline void s5pc1xx_phy_write_reg(int value, int offset)
+{
+       writel(value, phy_base + offset);
+}
+
+static inline int s5pc1xx_otg_read_reg(int offset)
+{
+       return readl(otg_base + offset);
+}
+
+static inline void s5pc1xx_otg_write_reg(int value, int offset)
+{
+       writel(value, otg_base + offset);
+}
+
+void s5p_usb_init_phy(void)
+{
+       if (cpu_is_s5pc110()) {
+               s5pc1xx_phy_write_reg(0xA0, OTG_PHYPWR);
+               s5pc1xx_phy_write_reg(0x3, OTG_PHYCTRL);
+       } else {
+               s5pc1xx_phy_write_reg(0x0, OTG_PHYPWR);
+#ifdef CONFIG_OTG_CLK_OSCC
+               s5pc1xx_phy_write_reg(0x22, OTG_PHYCTRL);
+#else
+               s5pc1xx_phy_write_reg(0x2, OTG_PHYCTRL);
+#endif
+       }
+
+       s5pc1xx_phy_write_reg(0x1, OTG_RSTCON);
+       udelay(20);
+       s5pc1xx_phy_write_reg(0x0, OTG_RSTCON);
+       udelay(20);
+}
+
+int s5p_usb_detect_irq(void)
+{
+       u32 status;
+       status = s5pc1xx_otg_read_reg(OTG_GINTSTS);
+       return (status & 0x800c3810);
+}
+
+void s5p_usb_clear_irq(void)
+{
+       s5pc1xx_otg_write_reg(0xffffffff, OTG_GINTSTS);
+}
+
+void s5p_usb_core_soft_reset(void)
+{
+       u32 tmp;
+
+       s5pc1xx_otg_write_reg(CORE_SOFT_RESET, OTG_GRSTCTL);
+
+       do {
+               tmp = s5pc1xx_otg_read_reg(OTG_GRSTCTL);
+       } while (!(tmp & AHB_MASTER_IDLE));
+}
+
+void s5p_usb_wait_cable_insert(void)
+{
+       u32 tmp;
+       int ucFirst = 1;
+
+       do {
+               udelay(50);
+
+               tmp = s5pc1xx_otg_read_reg(OTG_GOTGCTL);
+
+               if (tmp & (B_SESSION_VALID | A_SESSION_VALID)) {
+                       break;
+               } else if (ucFirst == 1) {
+                       printf("Insert a OTG cable into the connector!\n");
+                       ucFirst = 0;
+               }
+       } while (1);
+}
+
+void s5p_usb_init_core(void)
+{
+       s5pc1xx_otg_write_reg(PTXFE_HALF | NPTXFE_HALF | MODE_SLAVE |
+                       BURST_SINGLE | GBL_INT_UNMASK, OTG_GAHBCFG);
+
+       s5pc1xx_otg_write_reg(
+                0x0 << 15      /* PHY Low Power Clock sel */
+              | 0x1 << 14      /* Non-Periodic TxFIFO Rewind Enable */
+              | 0x5 << 10      /* Turnaround time */
+              | 0x0 << 9       /* 0:HNP disable, 1:HNP enable */
+              | 0x0 << 8       /* 0:SRP disable, 1:SRP enable */
+              | 0x0 << 7       /* ULPI DDR sel */
+              | 0x0 << 6       /* 0: high speed utmi+, 1: full speed serial */
+              | 0x0 << 4       /* 0: utmi+, 1:ulpi */
+              | 0x1 << 3       /* phy i/f  0:8bit, 1:16bit */
+              | 0x7 << 0,      /* HS/FS Timeout* */
+              OTG_GUSBCFG);
+}
+
+void s5p_usb_check_current_mode(u8 *pucMode)
+{
+       u32 tmp;
+
+       tmp = s5pc1xx_otg_read_reg(OTG_GINTSTS);
+       *pucMode = tmp & 0x1;
+}
+
+void s5p_usb_set_soft_disconnect(void)
+{
+       u32 tmp;
+
+       tmp = s5pc1xx_otg_read_reg(OTG_DCTL);
+       tmp |= SOFT_DISCONNECT;
+       s5pc1xx_otg_write_reg(tmp, OTG_DCTL);
+}
+
+void s5p_usb_clear_soft_disconnect(void)
+{
+       u32 tmp;
+
+       tmp = s5pc1xx_otg_read_reg(OTG_DCTL);
+       tmp &= ~SOFT_DISCONNECT;
+       s5pc1xx_otg_write_reg(tmp, OTG_DCTL);
+}
+
+void s5p_usb_init_device(void)
+{
+       s5pc1xx_otg_write_reg(1 << 18 | otg.speed << 0, OTG_DCFG);
+
+       s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
+                       INT_ENUMDONE | INT_RESET | INT_SUSPEND |
+                       INT_RX_FIFO_NOT_EMPTY, OTG_GINTMSK);
+}
+
+int s5p_usbctl_init(void)
+{
+       u8 ucMode;
+       u32 reg;
+
+       s5p_usb_init_base();
+
+       if (cpu_is_s5pc110()) {
+               reg = readl(S5PC110_USB_PHY_CON);
+               reg |= (1 << 0); /* USB PHY0 enable */
+               writel(reg, S5PC110_USB_PHY_CON);
+       } else {
+               reg = readl(S5PC100_OTHERS);
+               reg |= (1 << 16); /* unmask usb signal */
+               writel(reg, S5PC100_OTHERS);
+       }
+
+       otg.speed = speed;
+       otg.set_config = 0;
+       otg.ep0_state = EP0_STATE_INIT;
+       otg.ep0_substate = 0;
+
+       s5p_usb_init_phy();
+       s5p_usb_core_soft_reset();
+       s5p_usb_wait_cable_insert();
+       s5p_usb_init_core();
+       s5p_usb_check_current_mode(&ucMode);
+
+       if (ucMode == INT_DEV_MODE) {
+               s5p_usb_set_soft_disconnect();
+               udelay(10);
+               s5p_usb_clear_soft_disconnect();
+               s5p_usb_init_device();
+               return 0;
+       } else {
+               printf("Error : Current Mode is Host\n");
+               return 0;
+       }
+}
+
+int s5p_usbc_activate(void)
+{
+       return 0;
+}
+
+void s5p_usb_stop(void)
+{
+}
+
+void s5p_usb_set_inep_xfersize(EP_TYPE type, u32 pktcnt, u32 xfersize)
+{
+       if (type == EP_TYPE_CONTROL) {
+               s5pc1xx_otg_write_reg((pktcnt << 19) | (xfersize << 0),
+                               OTG_DIEPTSIZ0);
+       } else if (type == EP_TYPE_BULK) {
+               s5pc1xx_otg_write_reg((1 << 29) | (pktcnt << 19) |
+                               (xfersize << 0), OTG_DIEPTSIZ_IN);
+       }
+}
+
+void s5p_usb_set_outep_xfersize(EP_TYPE type, u32 pktcnt, u32 xfersize)
+{
+       if (type == EP_TYPE_CONTROL) {
+               s5pc1xx_otg_write_reg((1 << 29) | (pktcnt << 19) |
+                               (xfersize << 0), OTG_DOEPTSIZ0);
+       } else if (type == EP_TYPE_BULK) {
+               s5pc1xx_otg_write_reg((pktcnt << 19) | (xfersize << 0),
+                               OTG_DOEPTSIZ_OUT);
+       }
+}
+
+/* works on both aligned and unaligned buffers */
+void s5p_usb_write_ep0_fifo(u8 *buf, int num)
+{
+       int i;
+       u32 Wr_Data = 0;
+
+       for (i = 0; i < num; i += 4) {
+               Wr_Data = ((*(buf + 3)) << 24) |
+                       ((*(buf + 2)) << 16) |
+                       ((*(buf + 1)) << 8) |
+                       *buf;
+               s5pc1xx_otg_write_reg(Wr_Data, OTG_EP0_FIFO);
+               buf += 4;
+       }
+}
+
+/* optimized fifo access routines, warning: only aligned buffers are supported */
+static inline void s5p_usb_write_in_fifo(u8 *buf, int num)
+{
+       u32 fifo = otg_base + OTG_IN_FIFO;
+       u32 *p = (u32 *)buf;
+       int i;
+
+       for (i = 0; i < num; i += 4)
+               writel(*p++, fifo);
+}
+
+static inline void s5p_usb_read_out_fifo(u8 *buf, int num)
+{
+       u32 fifo = otg_base + OTG_OUT_FIFO;
+       u32 *p = (u32 *)buf;
+       int i;
+
+       for (i = 0; i < num; i += 4)
+               *p++ = readl(fifo);
+}
+
+void s5p_usb_get_desc(void)
+{
+       switch (otg.dev_req.wValue_H) {
+       case DEVICE_DESCRIPTOR:
+               otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
+                               otg.dev_req.wLength_L);
+               otg.ep0_state = EP0_STATE_GD_DEV_0;
+               break;
+
+       case CONFIGURATION_DESCRIPTOR:
+               otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
+                               otg.dev_req.wLength_L);
+
+               if (otg.req_length > CONFIG_DESC_SIZE)
+                       otg.ep0_state = EP0_STATE_GD_CFG_0;
+               else
+                       otg.ep0_state = EP0_STATE_GD_CFG_ONLY_0;
+               break;
+
+       case STRING_DESCRIPTOR:
+               switch (otg.dev_req.wValue_L) {
+               case 0:
+                       otg.ep0_state = EP0_STATE_GD_STR_I0;
+                       break;
+               case 1:
+                       otg.ep0_state = EP0_STATE_GD_STR_I1;
+                       break;
+               case 2:
+                       otg.ep0_state = EP0_STATE_GD_STR_I2;
+                       break;
+               default:
+                       break;
+               }
+               break;
+
+       case ENDPOINT_DESCRIPTOR:
+               switch (otg.dev_req.wValue_L & 0xf) {
+               case 0:
+                       otg.ep0_state = EP0_STATE_GD_EP0_ONLY_0;
+                       break;
+               case 1:
+                       otg.ep0_state = EP0_STATE_GD_EP1_ONLY_0;
+                       break;
+               default:
+                       break;
+               }
+               break;
+
+       case DEVICE_QUALIFIER:
+               otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
+                               otg.dev_req.wLength_L);
+               otg.ep0_state = EP0_STATE_GD_DEV_QUALIFIER;
+               break;
+
+       case OTHER_SPEED_CONFIGURATION:
+               otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
+                               otg.dev_req.wLength_L);
+               otg.ep0_state = EP0_STATE_GD_OTHER_SPEED;
+               break;
+       }
+}
+
+void s5p_usb_clear_feature(void)
+{
+       switch (otg.dev_req.bmRequestType) {
+       case DEVICE_RECIPIENT:
+               if (otg.dev_req.wValue_L == 1)
+                       remode_wakeup = 0;
+               break;
+
+       case ENDPOINT_RECIPIENT:
+               if (otg.dev_req.wValue_L == 0) {
+                       if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP)
+                               get_status.ep_ctrl = 0;
+
+                       /* IN Endpoint */
+                       if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP)
+                               get_status.ep_in = 0;
+
+                       /* OUT Endpoint */
+                       if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP)
+                               get_status.ep_out = 0;
+               }
+               break;
+
+       default:
+               break;
+       }
+       otg.ep0_state = EP0_STATE_INIT;
+}
+
+void s5p_usb_set_feature(void)
+{
+       switch (otg.dev_req.bmRequestType) {
+       case DEVICE_RECIPIENT:
+               if (otg.dev_req.wValue_L == 1)
+                       remode_wakeup = 1;
+               break;
+
+       case ENDPOINT_RECIPIENT:
+               if (otg.dev_req.wValue_L == 0) {
+                       if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP)
+                               get_status.ep_ctrl = 1;
+
+                       if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP)
+                               get_status.ep_in = 1;
+
+                       if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP)
+                               get_status.ep_out = 1;
+               }
+               break;
+
+       default:
+               break;
+       }
+
+       switch (otg.dev_req.wValue_L) {
+       case EP_STALL:
+               /* TBD: additional processing if required */
+               break;
+
+       case TEST_MODE:
+               /* not support */
+               break;
+
+       default:
+               break;
+       }
+       otg.ep0_state = EP0_STATE_INIT;
+}
+
+void s5p_usb_get_status(void)
+{
+       switch (otg.dev_req.bmRequestType) {
+       case (0x80):    /*device */
+               get_status.Device = ((u8) remode_wakeup << 1) | 0x1;
+               otg.ep0_state = EP0_STATE_GET_STATUS0;
+               break;
+
+       case (0x81):    /*interface */
+               get_status.Interface = 0;
+               otg.ep0_state = EP0_STATE_GET_STATUS1;
+               break;
+
+       case (0x82):    /*endpoint */
+               if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP)
+                       otg.ep0_state = EP0_STATE_GET_STATUS2;
+
+               if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP)
+                       otg.ep0_state = EP0_STATE_GET_STATUS3;
+
+               if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP)
+                       otg.ep0_state = EP0_STATE_GET_STATUS4;
+               break;
+
+       default:
+               break;
+       }
+}
+
+void s5p_usb_ep0_int_hndlr(void)
+{
+       u16 i;
+       u32 buf[2] = {0x0000, };
+       u16 addr;
+
+       if (otg.ep0_state == EP0_STATE_INIT) {
+               for (i = 0; i < 2; i++)
+                       buf[i] = s5pc1xx_otg_read_reg(OTG_EP0_FIFO);
+
+               otg.dev_req.bmRequestType = buf[0];
+               otg.dev_req.bRequest = buf[0] >> 8;
+               otg.dev_req.wValue_L = buf[0] >> 16;
+               otg.dev_req.wValue_H = buf[0] >> 24;
+               otg.dev_req.wIndex_L = buf[1];
+               otg.dev_req.wIndex_H = buf[1] >> 8;
+               otg.dev_req.wLength_L = buf[1] >> 16;
+               otg.dev_req.wLength_H = buf[1] >> 24;
+
+               switch (otg.dev_req.bRequest) {
+               case STANDARD_SET_ADDRESS:
+                       /* Set Address Update bit */
+                       addr = (otg.dev_req.wValue_L);
+                       s5pc1xx_otg_write_reg(1 << 18 | addr << 4 | otg.speed << 0,
+                              OTG_DCFG);
+                       otg.ep0_state = EP0_STATE_INIT;
+                       break;
+
+               case STANDARD_SET_DESCRIPTOR:
+                       break;
+
+               case STANDARD_SET_CONFIGURATION:
+                       /* Configuration value in configuration descriptor */
+                       config_value = otg.dev_req.wValue_L;
+                       otg.set_config = 1;
+                       otg.ep0_state = EP0_STATE_INIT;
+
+                       s5p_usb_connected = 1;
+                       break;
+
+               case STANDARD_GET_CONFIGURATION:
+                       s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
+
+                       /*ep0 enable, clear nak, next ep0, 8byte */
+                       s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+                       s5pc1xx_otg_write_reg(config_value, OTG_EP0_FIFO);
+                       otg.ep0_state = EP0_STATE_INIT;
+                       break;
+
+               case STANDARD_GET_DESCRIPTOR:
+                       s5p_usb_get_desc();
+                       break;
+
+               case STANDARD_CLEAR_FEATURE:
+                       s5p_usb_clear_feature();
+                       break;
+
+               case STANDARD_SET_FEATURE:
+                       s5p_usb_set_feature();
+                       break;
+
+               case STANDARD_GET_STATUS:
+                       s5p_usb_get_status();
+                       break;
+
+               case STANDARD_GET_INTERFACE:
+                       otg.ep0_state = EP0_STATE_INTERFACE_GET;
+                       break;
+
+               case STANDARD_SET_INTERFACE:
+                       get_intf.AlternateSetting = otg.dev_req.wValue_L;
+                       otg.ep0_state = EP0_STATE_INIT;
+                       break;
+
+               case STANDARD_SYNCH_FRAME:
+                       otg.ep0_state = EP0_STATE_INIT;
+                       break;
+
+               default:
+                       break;
+               }
+       }
+
+       s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, otg.ctrl_max_pktsize);
+
+       if (otg.speed == USB_HIGH) {
+               /*clear nak, next ep0, 64byte */
+               s5pc1xx_otg_write_reg(((1 << 26) | (CONTROL_EP << 11) | (0 << 0)),
+                      OTG_DIEPCTL0);
+       } else {
+               /*clear nak, next ep0, 8byte */
+               s5pc1xx_otg_write_reg(((1 << 26) | (CONTROL_EP << 11) | (3 << 0)),
+                      OTG_DIEPCTL0);
+       }
+
+}
+
+void s5p_usb_set_otherspeed_conf_desc(u32 length)
+{
+       /* Standard device descriptor */
+       if (otg.speed == USB_HIGH) {
+               if (length == 9) {
+                       s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 9);
+                       s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
+                       s5p_usb_write_ep0_fifo((u8 *) &config_full, 9);
+               } else if (length == 32) {
+                       s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 32);
+                       s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
+                       s5p_usb_write_ep0_fifo((u8 *) &config_full_total, 32);
+               }
+               otg.ep0_state = EP0_STATE_INIT;
+       } else {
+               if (length == 9) {
+                       s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 8);
+                       s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+                       s5p_usb_write_ep0_fifo((u8 *) &config_high, 8);
+               } else if (length == 32) {
+                       s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 8);
+                       s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
+                       s5p_usb_write_ep0_fifo((u8 *) &config_high_total, 8);
+               }
+               otg.ep0_state = EP0_STATE_GD_OTHER_SPEED_HIGH_1;
+       }
+}
+
+void s5p_usb_transfer_ep0(void)
+{
+       switch (otg.ep0_state) {
+       case EP0_STATE_INIT:
+               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 0);
+
+               /*ep0 enable, clear nak, next ep0, 8byte */
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               break;
+
+       case EP0_STATE_GD_DEV_0:
+               if (otg.speed == USB_HIGH) {
+                       /*ep0 enable, clear nak, next ep0, max 64byte */
+                       s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
+                       if (otg.req_length < DEVICE_DESC_SIZE) {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               otg.req_length);
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)),
+                                               otg.req_length);
+                       } else {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               DEVICE_DESC_SIZE);
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)),
+                                               DEVICE_DESC_SIZE);
+                       }
+                       otg.ep0_state = EP0_STATE_INIT;
+               } else {
+                       s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+                       if (otg.req_length < DEVICE_DESC_SIZE) {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               otg.req_length);
+                       } else {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               DEVICE_DESC_SIZE);
+                       }
+
+                       if (otg.req_length < FS_CTRL_PKT_SIZE) {
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)),
+                                               otg.req_length);
+                               otg.ep0_state = EP0_STATE_INIT;
+                       } else {
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)),
+                                               FS_CTRL_PKT_SIZE);
+                               otg.ep0_state = EP0_STATE_GD_DEV_1;
+                       }
+               }
+               break;
+
+       case EP0_STATE_GD_DEV_1:
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               if (otg.req_length < (2 * FS_CTRL_PKT_SIZE)) {
+                       s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
+                                       FS_CTRL_PKT_SIZE,
+                                       otg.req_length - FS_CTRL_PKT_SIZE);
+                       otg.ep0_state = EP0_STATE_INIT;
+               } else {
+                       s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
+                                       FS_CTRL_PKT_SIZE, FS_CTRL_PKT_SIZE);
+                       otg.ep0_state = EP0_STATE_GD_DEV_2;
+               }
+               break;
+
+       case EP0_STATE_GD_DEV_2:
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               if (otg.req_length < DEVICE_DESC_SIZE) {
+                       s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
+                                       (2 * FS_CTRL_PKT_SIZE),
+                                       otg.req_length - 2 * FS_CTRL_PKT_SIZE);
+               } else {
+                       s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
+                                       (2 * FS_CTRL_PKT_SIZE),
+                                       DEVICE_DESC_SIZE - 2 * FS_CTRL_PKT_SIZE);
+               }
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       case EP0_STATE_GD_CFG_0:
+               if (otg.speed == USB_HIGH) {
+                       s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
+                       if (otg.req_length < CONFIG_DESC_TOTAL_SIZE) {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               otg.req_length);
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
+                                               otg.req_length);
+                       } else {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               CONFIG_DESC_TOTAL_SIZE);
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
+                                               CONFIG_DESC_TOTAL_SIZE);
+                       }
+                       otg.ep0_state = EP0_STATE_INIT;
+               } else {
+                       s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+                       if (otg.req_length < CONFIG_DESC_TOTAL_SIZE) {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               otg.req_length);
+                       } else {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               CONFIG_DESC_TOTAL_SIZE);
+                       }
+                       if (otg.req_length < FS_CTRL_PKT_SIZE) {
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
+                                               otg.req_length);
+                               otg.ep0_state = EP0_STATE_INIT;
+                       } else {
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
+                                               FS_CTRL_PKT_SIZE);
+                               otg.ep0_state = EP0_STATE_GD_CFG_1;
+                       }
+               }
+               break;
+
+       case EP0_STATE_GD_CFG_1:
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               if (otg.req_length < (2 * FS_CTRL_PKT_SIZE)) {
+                       s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
+                                       FS_CTRL_PKT_SIZE,
+                                       (otg.req_length - FS_CTRL_PKT_SIZE));
+                       otg.ep0_state = EP0_STATE_INIT;
+               } else {
+                       s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
+                                       FS_CTRL_PKT_SIZE, FS_CTRL_PKT_SIZE);
+                       otg.ep0_state = EP0_STATE_GD_CFG_2;
+               }
+               break;
+
+       case EP0_STATE_GD_CFG_2:
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               if (otg.req_length < (3 * FS_CTRL_PKT_SIZE)) {
+                       s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
+                                       (2 * FS_CTRL_PKT_SIZE),
+                                       otg.req_length - 2 * FS_CTRL_PKT_SIZE);
+                       otg.ep0_state = EP0_STATE_INIT;
+               } else {
+                       s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
+                                       (2 * FS_CTRL_PKT_SIZE), FS_CTRL_PKT_SIZE);
+                       otg.ep0_state = EP0_STATE_GD_CFG_3;
+               }
+               break;
+
+       case EP0_STATE_GD_CFG_3:
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               if (otg.req_length < (4 * FS_CTRL_PKT_SIZE)) {
+                       s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
+                                       (3 * FS_CTRL_PKT_SIZE),
+                                       otg.req_length - 3 * FS_CTRL_PKT_SIZE);
+                       otg.ep0_state = EP0_STATE_INIT;
+               } else {
+                       s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
+                                       (3 * FS_CTRL_PKT_SIZE), FS_CTRL_PKT_SIZE);
+                       otg.ep0_state = EP0_STATE_GD_CFG_4;
+               }
+               break;
+
+       case EP0_STATE_GD_CFG_4:
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       case EP0_STATE_GD_DEV_QUALIFIER:
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
+               if (otg.req_length < 10) {
+                       s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                       otg.req_length);
+                       s5p_usb_write_ep0_fifo((u8 *)qualifier_desc,
+                                       otg.req_length);
+               } else {
+                       s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 10);
+                       s5p_usb_write_ep0_fifo((u8 *)qualifier_desc, 10);
+               }
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       case EP0_STATE_GD_OTHER_SPEED:
+               s5p_usb_set_otherspeed_conf_desc(otg.req_length);
+               break;
+
+       case EP0_STATE_GD_OTHER_SPEED_HIGH_1:
+               if (otg.req_length == 9) {
+                       s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
+                       s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+                       s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 8, 1);
+                       otg.ep0_state = EP0_STATE_INIT;
+               } else {
+                       s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 8);
+                       s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+                       s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 8, 8);
+                       otg.ep0_state = EP0_STATE_GD_OTHER_SPEED_HIGH_2;
+               }
+               break;
+
+       case EP0_STATE_GD_OTHER_SPEED_HIGH_2:
+               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 8);
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 16, 8);
+               otg.ep0_state = EP0_STATE_GD_OTHER_SPEED_HIGH_3;
+               break;
+
+       case EP0_STATE_GD_OTHER_SPEED_HIGH_3:
+               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 8);
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 24, 8);
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       case EP0_STATE_GD_CFG_ONLY_0:
+               if (otg.speed == USB_HIGH) {
+                       if (otg.req_length < CONFIG_DESC_SIZE) {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               otg.req_length);
+                               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
+                                               otg.req_length);
+                       } else {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               CONFIG_DESC_SIZE);
+                               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
+                                               CONFIG_DESC_SIZE);
+                       }
+                       otg.ep0_state = EP0_STATE_INIT;
+               } else {
+                       s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+                       if (otg.req_length < CONFIG_DESC_SIZE) {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               otg.req_length);
+                       } else {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               CONFIG_DESC_SIZE);
+                       }
+                       if (otg.req_length < FS_CTRL_PKT_SIZE) {
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
+                                               otg.req_length);
+                               otg.ep0_state = EP0_STATE_INIT;
+                       } else {
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
+                                               FS_CTRL_PKT_SIZE);
+                               otg.ep0_state = EP0_STATE_GD_CFG_ONLY_1;
+                       }
+               }
+               break;
+
+       case EP0_STATE_GD_CFG_ONLY_1:
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
+                               FS_CTRL_PKT_SIZE,
+                               CONFIG_DESC_SIZE - FS_CTRL_PKT_SIZE);
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       case EP0_STATE_GD_IF_ONLY_0:
+               if (otg.speed == USB_HIGH) {
+                       if (otg.req_length < INTERFACE_DESC_SIZE) {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               otg.req_length);
+                               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.intf)),
+                                               otg.req_length);
+                       } else {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               INTERFACE_DESC_SIZE);
+                               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.intf)),
+                                               INTERFACE_DESC_SIZE);
+                       }
+                       otg.ep0_state = EP0_STATE_INIT;
+               } else {
+                       s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+                       if (otg.req_length < INTERFACE_DESC_SIZE) {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               otg.req_length);
+                       } else {
+                               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
+                                               INTERFACE_DESC_SIZE);
+                       }
+                       if (otg.req_length < FS_CTRL_PKT_SIZE) {
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.intf)),
+                                               otg.req_length);
+                               otg.ep0_state = EP0_STATE_INIT;
+                       } else {
+                               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.intf)),
+                                               FS_CTRL_PKT_SIZE);
+                               otg.ep0_state = EP0_STATE_GD_IF_ONLY_1;
+                       }
+               }
+               break;
+
+       case EP0_STATE_GD_IF_ONLY_1:
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.intf)) +
+                               FS_CTRL_PKT_SIZE,
+                               INTERFACE_DESC_SIZE - FS_CTRL_PKT_SIZE);
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       case EP0_STATE_GD_EP0_ONLY_0:
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, ENDPOINT_DESC_SIZE);
+               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.ep1)),
+                               ENDPOINT_DESC_SIZE);
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       case EP0_STATE_GD_EP1_ONLY_0:
+               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, ENDPOINT_DESC_SIZE);
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.ep2)),
+                               ENDPOINT_DESC_SIZE);
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       case EP0_STATE_GD_STR_I0:
+               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, STRING_DESC0_SIZE);
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               s5p_usb_write_ep0_fifo((u8 *)string_desc0, STRING_DESC0_SIZE);
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       case EP0_STATE_GD_STR_I1:
+               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, sizeof(string_desc1));
+               if ((otg.ep0_substate * otg.ctrl_max_pktsize +
+                       otg.ctrl_max_pktsize) < sizeof(string_desc1)) {
+                       if (otg.speed == USB_HIGH)
+                               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
+                       else
+                               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+
+                       s5p_usb_write_ep0_fifo((u8 *)string_desc1 +
+                                       (otg.ep0_substate * otg.ctrl_max_pktsize),
+                                       otg.ctrl_max_pktsize);
+                       otg.ep0_state = EP0_STATE_GD_STR_I1;
+                       otg.ep0_substate++;
+               } else {
+                       if (otg.speed == USB_HIGH)
+                               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
+                       else
+                               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+
+                       s5p_usb_write_ep0_fifo((u8 *)string_desc1 +
+                                       (otg.ep0_substate * otg.ctrl_max_pktsize),
+                                       sizeof(string_desc1) - (otg.ep0_substate *
+                                               otg.ctrl_max_pktsize));
+                       otg.ep0_state = EP0_STATE_INIT;
+                       otg.ep0_substate = 0;
+               }
+               break;
+
+       case EP0_STATE_GD_STR_I2:
+               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, sizeof(string_desc2));
+               if ((otg.ep0_substate * otg.ctrl_max_pktsize +
+                       otg.ctrl_max_pktsize) < sizeof(string_desc2)) {
+                       if (otg.speed == USB_HIGH)
+                               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
+                       else
+                               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+
+                       s5p_usb_write_ep0_fifo((u8 *) string_desc2 +
+                                       (otg.ep0_substate * otg.ctrl_max_pktsize),
+                                       otg.ctrl_max_pktsize);
+                       otg.ep0_state = EP0_STATE_GD_STR_I2;
+                       otg.ep0_substate++;
+               } else {
+                       if (otg.speed == USB_HIGH)
+                               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
+                       else
+                               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+                       s5p_usb_write_ep0_fifo((u8 *) string_desc2 +
+                                       (otg.ep0_substate * otg.ctrl_max_pktsize),
+                                       sizeof(string_desc2) - (otg.ep0_substate *
+                                               otg.ctrl_max_pktsize));
+                       otg.ep0_state = EP0_STATE_INIT;
+                       otg.ep0_substate = 0;
+               }
+               break;
+
+       case EP0_STATE_INTERFACE_GET:
+               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               s5p_usb_write_ep0_fifo((u8 *) &get_intf, 1);
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       case EP0_STATE_GET_STATUS0:
+               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               s5p_usb_write_ep0_fifo((u8 *) &get_status, 1);
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       case EP0_STATE_GET_STATUS1:
+               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               s5p_usb_write_ep0_fifo((u8 *) &get_status + 1, 1);
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       case EP0_STATE_GET_STATUS2:
+               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               s5p_usb_write_ep0_fifo((u8 *) &get_status + 2, 1);
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       case EP0_STATE_GET_STATUS3:
+               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               s5p_usb_write_ep0_fifo((u8 *) &get_status + 3, 1);
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       case EP0_STATE_GET_STATUS4:
+               s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
+               s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
+               s5p_usb_write_ep0_fifo((u8 *) &get_status + 4, 1);
+               otg.ep0_state = EP0_STATE_INIT;
+               break;
+
+       default:
+               break;
+       }
+}
+
+void s5p_usb_tx(char *tx_data, int tx_size)
+{
+       otg.up_ptr = (u8 *) tx_data;
+       otg.up_addr = (u32) tx_data;
+       otg.up_size = tx_size;
+
+       if (otg.op_mode == USB_CPU) {
+               if (otg.up_size > otg.bulkin_max_pktsize) {
+                       s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1,
+                                       otg.bulkin_max_pktsize);
+               } else {
+                       s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1, otg.up_size);
+               }
+
+               /*ep1 enable, clear nak, bulk, usb active, max pkt */
+               s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
+                               otg.bulkin_max_pktsize << 0, OTG_DIEPCTL_IN);
+
+               s5p_usb_write_in_fifo(otg.up_ptr, otg.up_size);
+       } else if ((otg.op_mode == USB_DMA) && (otg.up_size > 0)) {
+               u32 pktcnt, remainder;
+
+               s5pc1xx_otg_write_reg(MODE_DMA | BURST_INCR4 | GBL_INT_UNMASK,
+                               OTG_GAHBCFG);
+               s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
+                               INT_ENUMDONE | INT_RESET | INT_SUSPEND,
+                               OTG_GINTMSK);
+
+               s5pc1xx_otg_write_reg((u32) otg.up_ptr, OTG_DIEPDMA_IN);
+
+               pktcnt = (u32) (otg.up_size / otg.bulkin_max_pktsize);
+               remainder = (u32) (otg.up_size % otg.bulkin_max_pktsize);
+               if (remainder != 0)
+                       pktcnt += 1;
+
+               if (pktcnt > 1023) {
+                       s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1023,
+                                       otg.bulkin_max_pktsize * 1023);
+               } else {
+                       s5p_usb_set_inep_xfersize(EP_TYPE_BULK, pktcnt,
+                                       otg.up_size);
+               }
+
+               /*ep1 enable, clear nak, bulk, usb active, next ep1, max pkt */
+               s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
+                               BULK_IN_EP << 11 | otg.bulkin_max_pktsize << 0,
+                               OTG_DIEPCTL_IN);
+       }
+}
+
+void s5p_usb_rx(u32 fifo_cnt_byte)
+{
+       if (otg.op_mode == USB_CPU) {
+               s5p_usb_read_out_fifo((u8 *)otg.dn_ptr, fifo_cnt_byte);
+               otg.dn_ptr += fifo_cnt_byte;
+
+               s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1,
+                               otg.bulkout_max_pktsize);
+
+               /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt */
+               s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
+                               otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
+
+               if (((u32)otg.dn_ptr - otg.dn_addr) >= (otg.dn_filesize))
+                       s5p_receive_done = 1;
+       } else if (otg.dn_filesize > otg.bulkout_max_pktsize) {
+               u32 pkt_cnt, remain_cnt;
+
+               s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
+                               INT_ENUMDONE | INT_RESET | INT_SUSPEND,
+                               OTG_GINTMSK);
+               s5pc1xx_otg_write_reg(MODE_DMA | BURST_INCR4 | GBL_INT_UNMASK,
+                               OTG_GAHBCFG);
+               s5pc1xx_otg_write_reg((u32) otg.dn_ptr, OTG_DOEPDMA_OUT);
+               pkt_cnt = (u32)(otg.dn_filesize - otg.bulkout_max_pktsize) /
+                               otg.bulkout_max_pktsize;
+               remain_cnt = (u32)((otg.dn_filesize - otg.bulkout_max_pktsize) %
+                               otg.bulkout_max_pktsize);
+
+               if (remain_cnt != 0)
+                       pkt_cnt += 1;
+
+               if (pkt_cnt > 1023) {
+                       s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1023,
+                                       otg.bulkout_max_pktsize * 1023);
+               } else {
+                       s5p_usb_set_outep_xfersize(EP_TYPE_BULK, pkt_cnt,
+                                       otg.dn_filesize - otg.bulkout_max_pktsize);
+               }
+
+               /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt */
+               s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
+                               otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
+       }
+}
+
+void s5p_usb_int_bulkout(u32 fifo_cnt_byte)
+{
+       s5p_usb_rx(fifo_cnt_byte);
+}
+
+void s5p_usb_dma_in_done(void)
+{
+       s32 remain_cnt;
+
+       otg.up_ptr = (u8 *)s5pc1xx_otg_read_reg(OTG_DIEPDMA_IN);
+       remain_cnt = otg.up_size - ((u32) otg.up_ptr - otg.up_addr);
+
+       if (remain_cnt > 0) {
+               u32 pktcnt, remainder;
+               pktcnt = (u32)(remain_cnt / otg.bulkin_max_pktsize);
+               remainder = (u32)(remain_cnt % otg.bulkin_max_pktsize);
+
+               if (remainder != 0)
+                       pktcnt += 1;
+
+               if (pktcnt > 1023) {
+                       s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1023,
+                                       otg.bulkin_max_pktsize * 1023);
+               } else {
+                       s5p_usb_set_inep_xfersize(EP_TYPE_BULK, pktcnt,
+                                       remain_cnt);
+               }
+
+               /*ep1 enable, clear nak, bulk, usb active, next ep1, max pkt */
+               s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
+                               BULK_IN_EP << 11 | otg.bulkin_max_pktsize << 0,
+                               OTG_DIEPCTL_IN);
+
+               s5p_receive_done = 1;
+       }
+}
+
+void s5p_usb_dma_out_done(void)
+{
+       s32 remain_cnt;
+
+       otg.dn_ptr = (u8 *)s5pc1xx_otg_read_reg(OTG_DOEPDMA_OUT);
+
+       remain_cnt = otg.dn_filesize - ((u32) otg.dn_ptr - otg.dn_addr + 8);
+
+       if (remain_cnt > 0) {
+               u32 pktcnt, remainder;
+               pktcnt = (u32)(remain_cnt / otg.bulkout_max_pktsize);
+               remainder = (u32)(remain_cnt % otg.bulkout_max_pktsize);
+
+               if (remainder != 0)
+                       pktcnt += 1;
+
+               if (pktcnt > 1023) {
+                       s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1023,
+                                       otg.bulkout_max_pktsize * 1023);
+               } else {
+                       s5p_usb_set_outep_xfersize(EP_TYPE_BULK, pktcnt,
+                                       remain_cnt);
+               }
+
+               /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt 64 */
+               s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
+                               otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
+       } else {
+               udelay(500);    /*for FPGA ??? */
+       }
+}
+
+void s5p_usb_set_all_outep_nak(void)
+{
+       u8 i;
+       u32 tmp;
+
+       for (i = 0; i < 16; i++) {
+               tmp = s5pc1xx_otg_read_reg(OTG_DOEPCTL0 + 0x20 * i);
+               tmp |= DEPCTL_SNAK;
+               s5pc1xx_otg_write_reg(tmp, OTG_DOEPCTL0 + 0x20 * i);
+       }
+}
+
+void s5p_usb_clear_all_outep_nak(void)
+{
+       u8 i;
+       u32 tmp;
+
+       for (i = 0; i < 16; i++) {
+               tmp = s5pc1xx_otg_read_reg(OTG_DOEPCTL0 + 0x20 * i);
+               tmp |= (DEPCTL_EPENA | DEPCTL_CNAK);
+               s5pc1xx_otg_write_reg(tmp, OTG_DOEPCTL0 + 0x20 * i);
+       }
+}
+
+void s5p_usb_set_max_pktsize(USB_SPEED speed)
+{
+       if (speed == USB_HIGH) {
+               otg.speed = USB_HIGH;
+               otg.ctrl_max_pktsize = HS_CTRL_PKT_SIZE;
+               otg.bulkin_max_pktsize = HS_BULK_PKT_SIZE;
+               otg.bulkout_max_pktsize = HS_BULK_PKT_SIZE;
+       } else {
+               otg.speed = USB_FULL;
+               otg.ctrl_max_pktsize = FS_CTRL_PKT_SIZE;
+               otg.bulkin_max_pktsize = FS_BULK_PKT_SIZE;
+               otg.bulkout_max_pktsize = FS_BULK_PKT_SIZE;
+       }
+}
+
+void s5p_usb_set_endpoint(void)
+{
+       /* Unmask OTG_DAINT source */
+       s5pc1xx_otg_write_reg(0xff, OTG_DIEPINT0);
+       s5pc1xx_otg_write_reg(0xff, OTG_DOEPINT0);
+       s5pc1xx_otg_write_reg(0xff, OTG_DIEPINT_IN);
+       s5pc1xx_otg_write_reg(0xff, OTG_DOEPINT_OUT);
+
+       /* Init For Ep0 */
+       if (otg.speed == USB_HIGH) {
+               /*MPS:64bytes */
+               s5pc1xx_otg_write_reg(((1 << 26) | (CONTROL_EP << 11) | (0 << 0)),
+                               OTG_DIEPCTL0);
+               /*ep0 enable, clear nak */
+               s5pc1xx_otg_write_reg((1u << 31) | (1 << 26) | (0 << 0),
+                               OTG_DOEPCTL0);
+       } else {
+               /*MPS:8bytes */
+               s5pc1xx_otg_write_reg(((1 << 26) | (CONTROL_EP << 11) | (3 << 0)),
+                               OTG_DIEPCTL0);
+               /*ep0 enable, clear nak */
+               s5pc1xx_otg_write_reg((1u << 31) | (1 << 26) | (3 << 0),
+                               OTG_DOEPCTL0);
+       }
+}
+
+void s5p_usb_set_descriptors(void)
+{
+#if defined (CONFIG_SAMSUNG_USB)
+       otg.desc.dev.bLength            = DEVICE_DESC_SIZE;
+       otg.desc.dev.bDescriptorType    = DEVICE_DESCRIPTOR;
+       otg.desc.dev.bDeviceClass       = 0xFF;
+       otg.desc.dev.bDeviceSubClass    = 0x0;
+       otg.desc.dev.bDeviceProtocol    = 0x0;
+       otg.desc.dev.bMaxPacketSize0    = otg.ctrl_max_pktsize;
+       otg.desc.dev.idVendorL          = 0xE8;
+       otg.desc.dev.idVendorH          = 0x04;
+       otg.desc.dev.idProductL         = 0x04;
+       otg.desc.dev.idProductH         = 0x12;
+       otg.desc.dev.iManufacturer      = 0x0;
+       otg.desc.dev.iProduct           = 0x2;
+       otg.desc.dev.iSerialNumber      = 0x0;
+       otg.desc.dev.bNumConfigurations = 0x1;
+       if (otg.speed == USB_FULL) {
+               otg.desc.dev.bcdUSBL    = 0x10;
+               otg.desc.dev.bcdUSBH    = 0x01;
+       } else {
+               otg.desc.dev.bcdUSBL    = 0x00;
+               otg.desc.dev.bcdUSBH    = 0x02;
+       }
+
+       otg.desc.config.bLength         = CONFIG_DESC_SIZE;
+       otg.desc.config.bDescriptorType = CONFIGURATION_DESCRIPTOR;
+       otg.desc.config.wTotalLengthL   = CONFIG_DESC_TOTAL_SIZE;
+       otg.desc.config.wTotalLengthH   = 0;
+       otg.desc.config.bNumInterfaces  = 1;
+       otg.desc.config.bConfigurationValue = 1;
+       otg.desc.config.iConfiguration  = 0;
+       otg.desc.config.bmAttributes    = CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED;
+       otg.desc.config.maxPower        = 50;
+#else
+       otg.desc.dev.bLength            = DEVICE_DESC_SIZE;
+       otg.desc.dev.bDescriptorType    = DEVICE_DESCRIPTOR;
+       otg.desc.dev.bDeviceClass       = 0xFF;
+       otg.desc.dev.bDeviceSubClass    = 0x0;
+       otg.desc.dev.bDeviceProtocol    = 0x0;
+       otg.desc.dev.bMaxPacketSize0    = otg.ctrl_max_pktsize;
+       otg.desc.dev.idVendorL          = 0xE8;
+       otg.desc.dev.idVendorH          = 0x04;
+       otg.desc.dev.idProductL         = 0x34;
+       otg.desc.dev.idProductH         = 0x12;
+       otg.desc.dev.bcdDeviceL         = 0x00;
+       otg.desc.dev.bcdDeviceH         = 0x01;
+       otg.desc.dev.iManufacturer      = 0x1;
+       otg.desc.dev.iProduct           = 0x2;
+       otg.desc.dev.iSerialNumber      = 0x0;
+       otg.desc.dev.bNumConfigurations = 0x1;
+       if (otg.speed == USB_FULL) {
+               otg.desc.dev.bcdUSBL    = 0x10;
+               otg.desc.dev.bcdUSBH    = 0x01;
+       } else {
+               otg.desc.dev.bcdUSBL    = 0x00;
+               otg.desc.dev.bcdUSBH    = 0x02;
+       }
+
+       otg.desc.config.bLength         = CONFIG_DESC_SIZE;
+       otg.desc.config.bDescriptorType = CONFIGURATION_DESCRIPTOR;
+       otg.desc.config.wTotalLengthL   = CONFIG_DESC_TOTAL_SIZE;
+       otg.desc.config.wTotalLengthH   = 0;
+       otg.desc.config.bNumInterfaces  = 1;
+       otg.desc.config.bConfigurationValue = 1;
+       otg.desc.config.iConfiguration  = 0;
+       otg.desc.config.bmAttributes    = CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED;
+       otg.desc.config.maxPower        = 25;
+#endif
+       otg.desc.intf.bLength           = INTERFACE_DESC_SIZE;
+       otg.desc.intf.bDescriptorType   = INTERFACE_DESCRIPTOR;
+       otg.desc.intf.bInterfaceNumber  = 0x0;
+       otg.desc.intf.bAlternateSetting = 0x0;
+       otg.desc.intf.bNumEndpoints     = 2;
+       otg.desc.intf.bInterfaceClass   = 0xff;
+       otg.desc.intf.bInterfaceSubClass = 0xff;
+       otg.desc.intf.bInterfaceProtocol = 0xff;
+       otg.desc.intf.iInterface        = 0x0;
+
+       otg.desc.ep1.bLength            = ENDPOINT_DESC_SIZE;
+       otg.desc.ep1.bDescriptorType    = ENDPOINT_DESCRIPTOR;
+       otg.desc.ep1.bEndpointAddress   = BULK_IN_EP | EP_ADDR_IN;
+       otg.desc.ep1.bmAttributes       = EP_ATTR_BULK;
+       otg.desc.ep1.wMaxPacketSizeL    = (u8)otg.bulkin_max_pktsize;
+       otg.desc.ep1.wMaxPacketSizeH    = (u8)(otg.bulkin_max_pktsize >> 8);
+       otg.desc.ep1.bInterval          = 0x0;
+
+       otg.desc.ep2.bLength            = ENDPOINT_DESC_SIZE;
+       otg.desc.ep2.bDescriptorType    = ENDPOINT_DESCRIPTOR;
+       otg.desc.ep2.bEndpointAddress   = BULK_OUT_EP | EP_ADDR_OUT;
+       otg.desc.ep2.bmAttributes       = EP_ATTR_BULK;
+       otg.desc.ep2.wMaxPacketSizeL    = (u8)otg.bulkout_max_pktsize;
+       otg.desc.ep2.wMaxPacketSizeH    = (u8)(otg.bulkout_max_pktsize >> 8);
+       otg.desc.ep2.bInterval          = 0x0;
+}
+
+void s5p_usb_check_speed(USB_SPEED *speed)
+{
+       u32 status;
+
+       status = s5pc1xx_otg_read_reg(OTG_DSTS);
+
+       *speed = (USB_SPEED)((status & 0x6) >> 1);
+}
+
+int s5p_usb_check_setconf(void)
+{
+       return otg.set_config;
+}
+
+void s5p_usb_set_opmode(USB_OPMODE mode)
+{
+       otg.op_mode = mode;
+
+       s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP | INT_ENUMDONE |
+                       INT_RESET | INT_SUSPEND | INT_RX_FIFO_NOT_EMPTY,
+                       OTG_GINTMSK);
+
+       s5pc1xx_otg_write_reg(MODE_SLAVE | BURST_SINGLE | GBL_INT_UNMASK,
+                       OTG_GAHBCFG);
+
+       s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1, otg.bulkout_max_pktsize);
+       s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1, 0);
+
+       /*bulk out ep enable, clear nak, bulk, usb active, next ep3, max pkt */
+       s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
+                       otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
+
+       /*bulk in ep enable, clear nak, bulk, usb active, next ep1, max pkt */
+       s5pc1xx_otg_write_reg(0u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
+                       otg.bulkin_max_pktsize << 0, OTG_DIEPCTL_IN);
+}
+
+void s5p_usb_reset(void)
+{
+       s5p_usb_set_all_outep_nak();
+
+       otg.ep0_state = EP0_STATE_INIT;
+       s5pc1xx_otg_write_reg(((1 << BULK_OUT_EP) | (1 << CONTROL_EP)) << 16 |
+                       ((1 << BULK_IN_EP) | (1 << CONTROL_EP)), OTG_DAINTMSK);
+       s5pc1xx_otg_write_reg(CTRL_OUT_EP_SETUP_PHASE_DONE | AHB_ERROR |
+                       TRANSFER_DONE, OTG_DOEPMSK);
+       s5pc1xx_otg_write_reg(INTKN_TXFEMP | NON_ISO_IN_EP_TIMEOUT | AHB_ERROR |
+                       TRANSFER_DONE, OTG_DIEPMSK);
+
+       /* Rx FIFO Size */
+       s5pc1xx_otg_write_reg(RX_FIFO_SIZE, OTG_GRXFSIZ);
+
+       /* Non Periodic Tx FIFO Size */
+       s5pc1xx_otg_write_reg(NPTX_FIFO_SIZE << 16 | NPTX_FIFO_START_ADDR << 0,
+                       OTG_GNPTXFSIZ);
+
+       s5p_usb_clear_all_outep_nak();
+
+       /*clear device address */
+       s5pc1xx_otg_write_reg(s5pc1xx_otg_read_reg(OTG_DCFG) & ~(0x7f << 4),
+                       OTG_DCFG);
+
+       if (SUSPEND_RESUME_ON) {
+               s5pc1xx_otg_write_reg(s5pc1xx_otg_read_reg(OTG_PCGCCTRL) & ~(1 << 0),
+                               OTG_PCGCCTRL);
+       }
+}
+
+int s5p_usb_set_init(void)
+{
+       u32 status;
+
+       status = s5pc1xx_otg_read_reg(OTG_DSTS);
+
+       /* Set if Device is High speed or Full speed */
+       if (((status & 0x6) >> 1) == USB_HIGH) {
+               s5p_usb_set_max_pktsize(USB_HIGH);
+       } else if (((status & 0x6) >> 1) == USB_FULL) {
+               s5p_usb_set_max_pktsize(USB_FULL);
+       } else {
+               printf("Error:Neither High_Speed nor Full_Speed\n");
+               return 0;
+       }
+
+       s5p_usb_set_endpoint();
+       s5p_usb_set_descriptors();
+       s5p_usb_set_opmode(op_mode);
+
+       return 1;
+}
+
+void s5p_usb_pkt_receive(void)
+{
+       u32 rx_status;
+       u32 fifo_cnt_byte;
+
+       rx_status = s5pc1xx_otg_read_reg(OTG_GRXSTSP);
+
+       if ((rx_status & (0xf << 17)) == SETUP_PKT_RECEIVED) {
+               s5p_usb_ep0_int_hndlr();
+       } else if ((rx_status & (0xf << 17)) == OUT_PKT_RECEIVED) {
+               fifo_cnt_byte = (rx_status & 0x7ff0) >> 4;
+
+               if ((rx_status & BULK_OUT_EP) && (fifo_cnt_byte)) {
+                       s5p_usb_int_bulkout(fifo_cnt_byte);
+                       if (otg.op_mode == USB_CPU) {
+                               s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP |
+                                       INT_IN_EP | INT_ENUMDONE | INT_RESET |
+                                       INT_SUSPEND | INT_RX_FIFO_NOT_EMPTY,
+                                       OTG_GINTMSK);
+                       }
+                       return;
+               }
+
+       } else if ((rx_status & (0xf << 17)) == GLOBAL_OUT_NAK) {
+               /* nop */
+       } else if ((rx_status & (0xf << 17)) == OUT_TRNASFER_COMPLETED) {
+               /* nop */
+       } else if ((rx_status & (0xf << 17)) == SETUP_TRANSACTION_COMPLETED) {
+               /* nop */
+       } else {
+               /* nop */
+       }
+}
+
+void s5p_usb_transfer(void)
+{
+       u32 ep_int;
+       u32 check_dma;
+       u32 ep_int_status;
+
+       ep_int = s5pc1xx_otg_read_reg(OTG_DAINT);
+
+       if (ep_int & (1 << CONTROL_EP)) {
+               ep_int_status = s5pc1xx_otg_read_reg(OTG_DIEPINT0);
+
+               if (ep_int_status & INTKN_TXFEMP) {
+                       u32 uNTxFifoSpace;
+                       do {
+                               uNTxFifoSpace = s5pc1xx_otg_read_reg(OTG_GNPTXSTS)
+                                               & 0xffff;
+                       } while (uNTxFifoSpace < otg.ctrl_max_pktsize);
+
+                       s5p_usb_transfer_ep0();
+               }
+
+               s5pc1xx_otg_write_reg(ep_int_status, OTG_DIEPINT0);
+       }
+
+       if (ep_int & ((1 << CONTROL_EP) << 16)) {
+               ep_int_status = s5pc1xx_otg_read_reg(OTG_DOEPINT0);
+
+               s5p_usb_set_outep_xfersize(EP_TYPE_CONTROL, 1, 8);
+               s5pc1xx_otg_write_reg(1u << 31 | 1 << 26, OTG_DOEPCTL0);
+
+               s5pc1xx_otg_write_reg(ep_int_status, OTG_DOEPINT0);
+       }
+
+       if (ep_int & (1 << BULK_IN_EP)) {
+               ep_int_status = s5pc1xx_otg_read_reg(OTG_DIEPINT_IN);
+
+               s5pc1xx_otg_write_reg(ep_int_status, OTG_DIEPINT_IN);
+               check_dma = s5pc1xx_otg_read_reg(OTG_GAHBCFG);
+
+               if ((check_dma & MODE_DMA) && (ep_int_status & TRANSFER_DONE))
+                       s5p_usb_dma_in_done();
+       }
+
+       if (ep_int & ((1 << BULK_OUT_EP) << 16)) {
+               ep_int_status = s5pc1xx_otg_read_reg(OTG_DOEPINT_OUT);
+
+               s5pc1xx_otg_write_reg(ep_int_status, OTG_DOEPINT_OUT);
+               check_dma = s5pc1xx_otg_read_reg(OTG_GAHBCFG);
+
+               if ((check_dma & MODE_DMA) && (ep_int_status & TRANSFER_DONE))
+                       s5p_usb_dma_out_done();
+       }
+}
+
+void s5p_udc_int_hndlr(void)
+{
+       u32 int_status;
+       int tmp;
+
+       int_status = s5pc1xx_otg_read_reg(OTG_GINTSTS);
+       s5pc1xx_otg_write_reg(int_status, OTG_GINTSTS);
+
+       if (int_status & INT_RESET) {
+               s5pc1xx_otg_write_reg(INT_RESET, OTG_GINTSTS);
+               s5p_usb_reset();
+       }
+
+       if (int_status & INT_ENUMDONE) {
+               s5pc1xx_otg_write_reg(INT_ENUMDONE, OTG_GINTSTS);
+
+               tmp = s5p_usb_set_init();
+               if (tmp == 0)
+                       return;
+       }
+
+       if (int_status & INT_RESUME) {
+               s5pc1xx_otg_write_reg(INT_RESUME, OTG_GINTSTS);
+
+               if (SUSPEND_RESUME_ON) {
+                       s5pc1xx_otg_write_reg(s5pc1xx_otg_read_reg(OTG_PCGCCTRL) &
+                                       ~(1 << 0), OTG_PCGCCTRL);
+               }
+       }
+
+       if (int_status & INT_SUSPEND) {
+               s5pc1xx_otg_write_reg(INT_SUSPEND, OTG_GINTSTS);
+
+               if (SUSPEND_RESUME_ON) {
+                       s5pc1xx_otg_write_reg(s5pc1xx_otg_read_reg(OTG_PCGCCTRL) |
+                                       (1 << 0), OTG_PCGCCTRL);
+               }
+       }
+
+       if (int_status & INT_RX_FIFO_NOT_EMPTY) {
+               s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
+                               INT_ENUMDONE | INT_RESET | INT_SUSPEND,
+                               OTG_GINTMSK);
+
+               s5p_usb_pkt_receive();
+
+               s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
+                               INT_ENUMDONE | INT_RESET | INT_SUSPEND |
+                               INT_RX_FIFO_NOT_EMPTY, OTG_GINTMSK);
+       }
+
+       if ((int_status & INT_IN_EP) || (int_status & INT_OUT_EP))
+               s5p_usb_transfer();
+}
diff --git a/cpu/arm1176/s5p64xx/usb-hs-otg.h b/cpu/arm1176/s5p64xx/usb-hs-otg.h
new file mode 100644 (file)
index 0000000..6d2e46e
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * (C) Copyright 2007
+ * Byungjae Lee, Samsung Erectronics, bjlee@samsung.com.
+ *     - only support for S3C6400
+ *
+ * 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 __USBD_HS_OTG_H__
+#define __USBD_HS_OTG_H__
+
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/arch/usb-hs-otg.h>
+
+#define make_word_c(w) __constant_cpu_to_le16(w)
+#define make_word(w)   __cpu_to_le16(w)
+
+#define CONTROL_EP             0
+#define BULK_IN_EP             1
+#define BULK_OUT_EP            2
+#define INTR_IN_EP             3
+
+#define FS_CTRL_PKT_SIZE       8
+#define FS_BULK_PKT_SIZE       64
+
+#define HS_CTRL_PKT_SIZE       64
+#define HS_BULK_PKT_SIZE       512
+
+#define RX_FIFO_SIZE           512
+#define NPTX_FIFO_START_ADDR   RX_FIFO_SIZE
+#define NPTX_FIFO_SIZE         512
+#define PTX_FIFO_SIZE          512
+
+/* string descriptor */
+#define LANGID_US_L            (0x09)
+#define LANGID_US_H            (0x04)
+
+/* Feature Selectors */
+#define EP_STALL               0
+#define DEVICE_REMOTE_WAKEUP   1
+#define TEST_MODE              2
+
+/* Test Mode Selector*/
+#define TEST_J                 1
+#define TEST_K                 2
+#define TEST_SE0_NAK           3
+#define TEST_PACKET            4
+#define TEST_FORCE_ENABLE      5
+
+#define OTG_DIEPCTL_IN         (OTG_DIEPCTL0 + 0x20 * BULK_IN_EP)
+#define OTG_DIEPINT_IN         (OTG_DIEPINT0 + 0x20 * BULK_IN_EP)
+#define OTG_DIEPTSIZ_IN                (OTG_DIEPTSIZ0 + 0x20 * BULK_IN_EP)
+#define OTG_DIEPDMA_IN         (OTG_DIEPDMA0 + 0x20 * BULK_IN_EP)
+#define OTG_DOEPCTL_OUT                (OTG_DOEPCTL0 + 0x20 * BULK_OUT_EP)
+#define OTG_DOEPINT_OUT                (OTG_DOEPINT0 + 0x20 * BULK_OUT_EP)
+#define OTG_DOEPTSIZ_OUT       (OTG_DOEPTSIZ0 + 0x20 * BULK_OUT_EP)
+#define OTG_DOEPDMA_OUT                (OTG_DOEPDMA0 + 0x20 * BULK_OUT_EP)
+#define OTG_IN_FIFO            (OTG_EP0_FIFO + 0x1000 * BULK_IN_EP)
+#define OTG_OUT_FIFO           (OTG_EP0_FIFO + 0x1000 * BULK_OUT_EP)
+
+typedef struct {
+       u8 bLength;
+       u8 bDescriptorType;
+       u8 bcdUSBL;
+       u8 bcdUSBH;
+       u8 bDeviceClass;
+       u8 bDeviceSubClass;
+       u8 bDeviceProtocol;
+       u8 bMaxPacketSize0;
+       u8 idVendorL;
+       u8 idVendorH;
+       u8 idProductL;
+       u8 idProductH;
+       u8 bcdDeviceL;
+       u8 bcdDeviceH;
+       u8 iManufacturer;
+       u8 iProduct;
+       u8 iSerialNumber;
+       u8 bNumConfigurations;
+} __attribute__ ((packed)) device_desc_t;
+
+typedef struct {
+       u8 bLength;
+       u8 bDescriptorType;
+       u8 wTotalLengthL;
+       u8 wTotalLengthH;
+       u8 bNumInterfaces;
+       u8 bConfigurationValue;
+       u8 iConfiguration;
+       u8 bmAttributes;
+       u8 maxPower;
+} __attribute__ ((packed)) config_desc_t;
+
+typedef struct {
+       u8 bLength;
+       u8 bDescriptorType;
+       u8 bInterfaceNumber;
+       u8 bAlternateSetting;
+       u8 bNumEndpoints;
+       u8 bInterfaceClass;
+       u8 bInterfaceSubClass;
+       u8 bInterfaceProtocol;
+       u8 iInterface;
+} __attribute__ ((packed)) intf_desc_t;
+
+typedef struct {
+       u8 bLength;
+       u8 bDescriptorType;
+       u8 bEndpointAddress;
+       u8 bmAttributes;
+       u8 wMaxPacketSizeL;
+       u8 wMaxPacketSizeH;
+       u8 bInterval;
+} __attribute__ ((packed)) ep_desc_t;
+
+typedef struct {
+       u8 bLength;
+       u8 bDescriptorType;
+   u16 bString[30];
+} __attribute__ ((packed)) string_desc_t;
+
+typedef struct {
+       u8 bmRequestType;
+       u8 bRequest;
+       u8 wValue_L;
+       u8 wValue_H;
+       u8 wIndex_L;
+       u8 wIndex_H;
+       u8 wLength_L;
+       u8 wLength_H;
+} __attribute__ ((packed)) device_req_t;
+
+typedef struct {
+       device_desc_t dev;
+       config_desc_t config;
+       intf_desc_t intf;
+       ep_desc_t ep1;
+       ep_desc_t ep2;
+       ep_desc_t ep3;
+       ep_desc_t ep4;
+} __attribute__ ((packed)) descriptors_t;
+
+typedef struct {
+       u8 Device;
+       u8 Interface;
+       u8 ep_ctrl;
+       u8 ep_in;
+       u8 ep_out;
+} __attribute__ ((packed)) get_status_t;
+
+typedef struct {
+       u8 AlternateSetting;
+} __attribute__ ((packed)) get_intf_t;
+
+typedef enum {
+       USB_CPU, USB_DMA
+} USB_OPMODE;
+
+typedef enum {
+       USB_HIGH, USB_FULL, USB_LOW
+} USB_SPEED;
+
+typedef enum {
+       EP_TYPE_CONTROL, EP_TYPE_ISOCHRONOUS, EP_TYPE_BULK, EP_TYPE_INTERRUPT
+} EP_TYPE;
+
+typedef struct {
+       descriptors_t desc;
+       device_req_t dev_req;
+
+       u32 ep0_state;
+       u32 ep0_substate;
+       USB_OPMODE op_mode;
+       USB_SPEED speed;
+       u32 ctrl_max_pktsize;
+       u32 bulkin_max_pktsize;
+       u32 bulkout_max_pktsize;
+       u32 dn_addr;
+       u32 dn_filesize;
+       u32 up_addr;
+       u32 up_size;
+       u8 *dn_ptr;
+       u8 *up_ptr;
+       u32 set_config;
+       u32 req_length;
+} __attribute__ ((packed)) otg_dev_t;
+
+enum DEV_REQUEST_DIRECTION {
+       HOST_TO_DEVICE = 0x00,
+       DEVICE_TO_HOST = 0x80
+};
+
+enum DEV_REQUEST_TYPE {
+       STANDARD_TYPE = 0x00,
+       CLASS_TYPE = 0x20,
+       VENDOR_TYPE = 0x40,
+       RESERVED_TYPE = 0x60
+};
+
+enum DEV_REQUEST_RECIPIENT {
+       DEVICE_RECIPIENT = 0,
+       INTERFACE_RECIPIENT = 1,
+       ENDPOINT_RECIPIENT = 2,
+       OTHER_RECIPIENT = 3
+};
+
+enum DESCRIPTOR_TYPE {
+       DEVICE_DESCRIPTOR = 1,
+       CONFIGURATION_DESCRIPTOR = 2,
+       STRING_DESCRIPTOR = 3,
+       INTERFACE_DESCRIPTOR = 4,
+       ENDPOINT_DESCRIPTOR = 5,
+       DEVICE_QUALIFIER = 6,
+       OTHER_SPEED_CONFIGURATION = 7,
+       INTERFACE_POWER = 8
+};
+
+enum CONFIG_ATTRIBUTES {
+       CONF_ATTR_DEFAULT = 0x80,
+       CONF_ATTR_REMOTE_WAKEUP = 0x20,
+       CONF_ATTR_SELFPOWERED = 0x40
+};
+
+enum ENDPOINT_ATTRIBUTES {
+       EP_ADDR_IN = 0x80,
+       EP_ADDR_OUT = 0x00,
+       EP_ATTR_CONTROL = 0x0,
+       EP_ATTR_ISOCHRONOUS = 0x1,
+       EP_ATTR_BULK = 0x2,
+       EP_ATTR_INTERRUPT = 0x3
+};
+
+enum STANDARD_REQUEST_CODE {
+       STANDARD_GET_STATUS = 0,
+       STANDARD_CLEAR_FEATURE = 1,
+       STANDARD_RESERVED_1 = 2,
+       STANDARD_SET_FEATURE = 3,
+       STANDARD_RESERVED_2 = 4,
+       STANDARD_SET_ADDRESS = 5,
+       STANDARD_GET_DESCRIPTOR = 6,
+       STANDARD_SET_DESCRIPTOR = 7,
+       STANDARD_GET_CONFIGURATION = 8,
+       STANDARD_SET_CONFIGURATION = 9,
+       STANDARD_GET_INTERFACE = 10,
+       STANDARD_SET_INTERFACE = 11,
+       STANDARD_SYNCH_FRAME = 12
+};
+
+int s5p_usbctl_init(void);
+int s5p_usbc_activate(void);
+void s5p_usb_stop(void);
+void s5p_udc_int_hndlr(void);
+void s5p_usb_tx(char *tx_data, int tx_size);
+int s5p_usb_detect_irq(void);
+void s5p_usb_clear_irq(void);
+
+/* in usbd-otg-hs.c */
+extern unsigned int s5p_usbd_dn_addr;
+extern unsigned int s5p_usbd_dn_cnt;
+extern int s5p_got_header;
+extern int s5p_receive_done;
+
+#endif
diff --git a/cpu/arm1176/s5p64xx/usb_downloader.c b/cpu/arm1176/s5p64xx/usb_downloader.c
new file mode 100644 (file)
index 0000000..c641663
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include "usbd.h"
+#include "usb-hs-otg.h"
+#ifdef CONFIG_S5PC1XXFB
+#include <fbutils.h>
+#endif
+
+static char tx_data[8] = "MPL";
+static long tx_len = 4;
+
+static char rx_data[2048];
+static long rx_len = 64;
+
+extern int s5p_receive_done;
+extern int s5p_usb_connected;
+extern otg_dev_t otg;
+
+static int __usb_board_init(void)
+{
+       return 0;
+}
+
+int usb_board_init(void) __attribute__((weak, alias("__usb_board_init")));
+
+/* clear download informations */
+static void s5p_usb_clear_dnfile_info(void)
+{
+       otg.dn_addr = 0;
+       otg.dn_filesize = 0;
+       otg.dn_ptr = 0;
+}
+
+/* clear upload informations */
+static void s5p_usb_clear_upfile_info(void)
+{
+       otg.up_addr = 0;
+       otg.up_size = 0;
+       otg.up_ptr = 0;
+}
+
+/* start the usb controller */
+static void usb_init(void)
+{
+       if (usb_board_init()) {
+               printf("Failed to usb_board_init\n");
+               return;
+       }
+
+#ifdef CONFIG_S5PC1XXFB
+       init_font();
+       set_font_color(FONT_WHITE);
+       fb_printf("Ready to USB Connection\n");
+#endif
+
+       s5p_usbctl_init();
+       s5p_usbc_activate();
+
+       printf("USB Start!! - %s Speed\n",
+                       otg.speed ? "Full" : "High");
+
+       while (!s5p_usb_connected) {
+               if (s5p_usb_detect_irq()) {
+                       s5p_udc_int_hndlr();
+                       s5p_usb_clear_irq();
+               }
+       }
+
+       s5p_usb_clear_dnfile_info();
+
+       printf("Connected!!\n");
+
+#ifdef CONFIG_S5PC1XXFB
+       fb_printf("Download Start\n");
+       draw_progress(40, 0, FONT_WHITE);
+#endif
+}
+
+static void usb_stop(void)
+{
+       s5p_usb_stop();
+#ifdef CONFIG_S5PC1XXFB
+       exit_font();
+
+       /* it uses fb3 as default window. */
+       s5pc_fimd_lcd_off(3);
+       s5pc_fimd_window_off(3);
+#endif
+}
+
+/*
+ * receive the packet from host PC
+ * return received size
+ */
+static int usb_receive_packet(void)
+{
+       while (1) {
+               if (s5p_usb_detect_irq()) {
+                       s5p_udc_int_hndlr();
+                       s5p_usb_clear_irq();
+               }
+
+               if (s5p_receive_done) {
+                       s5p_receive_done = 0;
+                       return otg.dn_filesize;
+               }
+       }
+}
+
+/* setup the download informations */
+static void recv_setup(char *addr, int len)
+{
+       s5p_usb_clear_dnfile_info();
+
+       otg.dn_addr = (u32)addr;
+       otg.dn_ptr = (u8 *) addr;
+       otg.dn_filesize = len;
+}
+
+#ifdef CONFIG_GENERIC_MMC
+#include <mmc.h>
+
+static void usbd_set_mmc_dev(struct usbd_ops *usbd)
+{
+       struct mmc *mmc;
+
+       usbd->mmc_dev = 0;
+       /* FIX 0x400 */
+       usbd->mmc_max = 0x400;
+       /* get from mmc->capacity?? */
+       usbd->mmc_total = 0xf50000;     /* 8GB / 0x200  */
+
+       mmc = find_mmc_device(usbd->mmc_dev);
+       mmc_init(mmc);
+
+       usbd->mmc_blk = mmc->read_bl_len;
+}
+#endif
+
+#ifdef CONFIG_S5PC1XXFB
+static void set_progress(int progress)
+{
+       draw_progress(40, progress, FONT_WHITE);
+}
+#endif
+/*
+ * This function is interfaced between
+ * USB Device Controller and USB Downloader
+ */
+struct usbd_ops *usbd_set_interface(struct usbd_ops *usbd)
+{
+       usbd->usb_init = usb_init;
+       usbd->usb_stop = usb_stop;
+       usbd->send_data = s5p_usb_tx;
+       usbd->recv_data = usb_receive_packet;
+       usbd->recv_setup = recv_setup;
+       usbd->tx_data = tx_data;
+       usbd->rx_data = rx_data;
+       usbd->tx_len = tx_len;
+       usbd->rx_len = rx_len;
+       usbd->ram_addr = CONFIG_SYS_DOWN_ADDR;
+#ifdef CONFIG_S5PC1XXFB
+       usbd->set_progress = set_progress;
+#endif
+#ifdef CONFIG_GENERIC_MMC
+       usbd_set_mmc_dev(usbd);
+#endif
+
+       return usbd;
+}
index 68a356d..e48999e 100644 (file)
@@ -35,7 +35,9 @@
 #ifdef CONFIG_ENABLE_MMU
 #include <asm/proc/domain.h>
 #endif
+#ifdef CONFIG_S3C64XX
 #include <asm/arch/s3c6400.h>
+#endif
 
 #if !defined(CONFIG_ENABLE_MMU) && !defined(CONFIG_SYS_PHY_UBOOT_BASE)
 #define CONFIG_SYS_PHY_UBOOT_BASE      CONFIG_SYS_UBOOT_BASE
index 3c77a7c..5f0eebb 100644 (file)
@@ -34,6 +34,7 @@ COBJS-$(CONFIG_SYS_NS16550) += ns16550.o
 COBJS-$(CONFIG_DRIVER_S3C4510_UART) += s3c4510b_uart.o
 COBJS-$(CONFIG_S3C64XX) += s3c64xx.o
 COBJS-$(CONFIG_S5PC1XX) += serial_s5pc1xx.o
+COBJS-$(CONFIG_S5P64XX) += serial_s5pc1xx.o
 COBJS-$(CONFIG_SYS_NS16550_SERIAL) += serial.o
 COBJS-$(CONFIG_CLPS7111_SERIAL) += serial_clps7111.o
 COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o
index 73669a9..6cd0c17 100644 (file)
@@ -31,10 +31,15 @@ static inline struct s5pc1xx_uart *s5pc1xx_get_base_uart(int dev_index)
 {
        u32 offset = dev_index * sizeof(struct s5pc1xx_uart);
 
+#ifdef CONFIG_S5PC1XX
        if (cpu_is_s5pc100())
                return (struct s5pc1xx_uart *)(S5PC100_UART_BASE + offset);
        else
                return (struct s5pc1xx_uart *)(S5PC110_UART_BASE + offset);
+#elif CONFIG_S5P64XX
+       if (cpu_is_s5p6442())
+               return (struct s5pc1xx_uart *)(S5P6442_UART_BASE + offset);
+#endif
 }
 
 /*
diff --git a/include/asm-arm/arch-s5p64xx/clk.h b/include/asm-arm/arch-s5p64xx/clk.h
new file mode 100644 (file)
index 0000000..9feb3e6
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARM_ARCH_CLK_H_
+#define __ASM_ARM_ARCH_CLK_H_
+
+void s5p64xx_clock_init(void);
+
+extern unsigned long (*get_pll_clk)(int pllreg);
+extern unsigned long (*get_arm_clk)(void);
+extern unsigned long (*get_pclk)(void);
+
+#endif
diff --git a/include/asm-arm/arch-s5p64xx/clock.h b/include/asm-arm/arch-s5p64xx/clock.h
new file mode 100644 (file)
index 0000000..e7df0b4
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARM_ARCH_CLOCK_H_
+#define __ASM_ARM_ARCH_CLOCK_H_
+
+#define APLL   0
+#define MPLL   1
+#define EPLL   2
+#define HPLL   3
+#define VPLL   4
+
+#define S5P6442_APLL_LOCK              0xE0100000
+#define S5P6442_MPLL_LOCK              0xE0100008
+#define S5P6442_EPLL_LOCK              0xE0100010
+#define S5P6442_VPLL_LOCK              0xE0100020
+#define S5P6442_APLL_CON               0xE0100100
+#define S5P6442_MPLL_CON               0xE0100108
+#define S5P6442_EPLL_CON               0xE0100110
+#define S5P6442_VPLL_CON               0xE0100120
+
+#ifndef __ASSEMBLY__
+struct s5p6442_clock {
+       unsigned int    apll_lock;
+       unsigned char   res1[0x4];
+       unsigned int    mpll_lock;
+       unsigned char   res2[0x4];
+       unsigned int    epll_lock;
+       unsigned char   res3[0xc];
+       unsigned int    vpll_lock;
+       unsigned char   res4[0xdc];
+       unsigned int    apll_con;
+       unsigned char   res5[0x4];
+       unsigned int    mpll_con;
+       unsigned char   res6[0x4];
+       unsigned int    epll_con;
+       unsigned char   res7[0xc];
+       unsigned int    vpll_con;
+       unsigned char   res8[0xdc];
+       unsigned int    src0;
+       unsigned int    src1;
+       unsigned int    src2;
+       unsigned int    src3;
+       unsigned int    src4;
+       unsigned int    src5;
+       unsigned int    src6;
+       unsigned char   res9[0xe4];
+       unsigned int    div0;
+       unsigned int    div1;
+       unsigned int    div2;
+       unsigned int    div3;
+       unsigned int    div4;
+       unsigned int    div5;
+       unsigned int    div6;
+       unsigned char   res10[0x1e4];
+       unsigned int    gate_d00;
+       unsigned int    gate_d01;
+       unsigned int    gate_d02;
+       unsigned char   res11[0x54];
+       unsigned int    gate_sclk0;
+       unsigned int    gate_sclk1;
+};
+#endif
+
+#endif
diff --git a/include/asm-arm/arch-s5p64xx/cpu.h b/include/asm-arm/arch-s5p64xx/cpu.h
new file mode 100644 (file)
index 0000000..cd84e5d
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef _S5P64XX_CPU_H
+#define _S5P64XX_CPU_H
+
+#define S5P64XX_ADDR_BASE      0xE0000000
+
+#define S5P64XX_CLOCK_BASE     0xE0100000
+
+/* S5P6442 */
+#define S5P6442_GPIO_BASE      0xE0200000
+#define S5P6442_SROMC_BASE     0xE7000000
+#define S5P6442_DMC_BASE       0xE6000000
+#define S5P6442_VIC0_BASE      0xE4000000
+#define S5P6442_VIC1_BASE      0xE4100000
+#define S5P6442_VIC2_BASE      0xE4200000
+#define S5P6442_PWMTIMER_BASE  0xEA000000
+#define S5P6442_WATCHDOG_BASE  0xEA200000
+#define S5P6442_UART_BASE      0xEC000000
+
+/* Chip ID */
+#define S5P64XX_PRO_ID         0xE0000000
+
+#ifndef __ASSEMBLY__
+/* CPU detection macros */
+extern unsigned int s5p64xx_cpu_id;
+
+#define IS_SAMSUNG_TYPE(type, id)                      \
+static inline int cpu_is_##type(void)                  \
+{                                                      \
+       return s5p64xx_cpu_id == id ? 1 : 0;            \
+}
+
+IS_SAMSUNG_TYPE(s5p6442, 0x6442)
+
+#endif
+
+#endif /* _S5P6442_CPU_H */
diff --git a/include/asm-arm/arch-s5p64xx/gpio.h b/include/asm-arm/arch-s5p64xx/gpio.h
new file mode 100644 (file)
index 0000000..0bda7a3
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+#ifndef __ASSEMBLY__
+struct s5p_gpio_bank {
+       unsigned int    con;
+       unsigned int    dat;
+       unsigned int    pull;
+       unsigned int    drv;
+       unsigned int    pdn_con;
+       unsigned int    pdn_pull;
+       unsigned char   res1[8];
+};
+
+struct s5p6442_gpio {
+       struct s5p_gpio_bank gpio_a0;
+       struct s5p_gpio_bank gpio_a1;
+       struct s5p_gpio_bank gpio_b;
+       struct s5p_gpio_bank gpio_c0;
+       struct s5p_gpio_bank gpio_c1;
+       struct s5p_gpio_bank gpio_d0;
+       struct s5p_gpio_bank gpio_d1;
+       struct s5p_gpio_bank gpio_e0;
+       struct s5p_gpio_bank gpio_e1;
+       struct s5p_gpio_bank gpio_f0;
+       struct s5p_gpio_bank gpio_f1;
+       struct s5p_gpio_bank gpio_f2;
+       struct s5p_gpio_bank gpio_f3;
+       struct s5p_gpio_bank gpio_g0;
+       struct s5p_gpio_bank gpio_g1;
+       struct s5p_gpio_bank gpio_g2;
+       struct s5p_gpio_bank gpio_j0;
+       struct s5p_gpio_bank gpio_j1;
+       struct s5p_gpio_bank gpio_j2;
+       struct s5p_gpio_bank gpio_j3;
+       struct s5p_gpio_bank gpio_j4;
+       struct s5p_gpio_bank gpio_mp0_1;
+       struct s5p_gpio_bank gpio_mp0_2;
+       struct s5p_gpio_bank gpio_mp0_3;
+       struct s5p_gpio_bank gpio_mp0_4;
+       struct s5p_gpio_bank gpio_mp0_5;
+       struct s5p_gpio_bank gpio_mp0_6;
+       struct s5p_gpio_bank gpio_mp0_7;
+       struct s5p_gpio_bank gpio_mp1_0;
+       struct s5p_gpio_bank gpio_mp1_1;
+       struct s5p_gpio_bank gpio_mp1_2;
+       struct s5p_gpio_bank gpio_mp1_3;
+       struct s5p_gpio_bank gpio_mp1_4;
+       struct s5p_gpio_bank gpio_mp1_5;
+       struct s5p_gpio_bank gpio_mp1_6;
+       struct s5p_gpio_bank gpio_mp1_7;
+       struct s5p_gpio_bank gpio_mp1_8;
+       struct s5p_gpio_bank res1[59];
+       struct s5p_gpio_bank gpio_h0;
+       struct s5p_gpio_bank gpio_h1;
+       struct s5p_gpio_bank gpio_h2;
+       struct s5p_gpio_bank gpio_h3;
+};
+
+/* functions */
+void gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg);
+void gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int enable);
+void gpio_direction_input(struct s5p_gpio_bank *bank, int gpio);
+void gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int enable);
+unsigned int gpio_get_value(struct s5p_gpio_bank *bank, int gpio);
+void gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode);
+void gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode);
+void gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode);
+#endif
+
+/* Pin configurations */
+#define GPIO_INPUT     0x0
+#define GPIO_OUTPUT    0x1
+#define GPIO_IRQ       0xf
+#define GPIO_FUNC(x)   (x)
+
+/* Pull mode */
+#define GPIO_PULL_NONE 0x0
+#define GPIO_PULL_DOWN 0x1
+#define GPIO_PULL_UP   0x2
+
+/* Drive Strength level */
+#define GPIO_DRV_1x    0x0
+#define GPIO_DRV_2x    0x1
+#define GPIO_DRV_3x    0x2
+#define GPIO_DRV_4x    0x3
+#define GPIO_DRV_FAST  0x0
+#define GPIO_DRV_SLOW  0x1
+
+#endif
diff --git a/include/asm-arm/arch-s5p64xx/i2c.h b/include/asm-arm/arch-s5p64xx/i2c.h
new file mode 100644 (file)
index 0000000..35a904a
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ * Kyungnin Park <kyungmin.park@samsung.com>
+ *
+ * based on s3c24x0_i2c.c
+ *
+ * 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 __ASM_ARCH_I2C_H_
+#define __ASM_ARCH_I2C_H_
+
+/* I2C */
+#define S5PC100_I2C0_BASE      0xEC100000
+#define S5PC100_I2C1_BASE      0xEC200000
+#define S5PC110_I2C0_BASE      0xE1800000
+#define S5PC110_I2C2_BASE      0xE1A00000
+
+#ifndef __ASSEMBLY__
+typedef struct s5pc1xx_i2c {
+       volatile unsigned long  IICCON;
+       volatile unsigned long  IICSTAT;
+       volatile unsigned long  IICADD;
+       volatile unsigned long  IICDS;
+       volatile unsigned long  IICLC;
+} s5pc1xx_i2c_t;
+#endif
+
+#endif
diff --git a/include/asm-arm/arch-s5p64xx/keypad.h b/include/asm-arm/arch-s5p64xx/keypad.h
new file mode 100644 (file)
index 0000000..97aafb0
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Kyungnin Park <kyungmin.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_KEYPAD_H_
+#define __ASM_ARCH_KEYPAD_H_
+
+/* I2C */
+#define S5PC100_KEYPAD_BASE            0xF3100000
+#define S5PC110_KEYPAD_BASE            0xE1600000
+
+#define S5PC1XX_KEYIFCON_OFFSET                (0x00)
+#define S5PC1XX_KEYIFSTSCLR_OFFSET     (0x04)
+#define S5PC1XX_KEYIFCOL_OFFSET                (0x08)
+#define S5PC1XX_KEYIFROW_OFFSET                (0x0C)
+#define S5PC1XX_KEYIFFC_OFFSET         (0x10)
+
+#endif
diff --git a/include/asm-arm/arch-s5p64xx/mem.h b/include/asm-arm/arch-s5p64xx/mem.h
new file mode 100644 (file)
index 0000000..97c04a0
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * (C) Copyright 2009
+ * Samsung Electronics, <www.samsung.com/sec>
+ * Heungjun Kim <riverful.kim@samsung.com>
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARM_ARCH_MEM_H_
+#define __ASM_ARM_ARCH_MEM_H_
+
+/* DRAM Memory Controller */
+#define CONCONTROL_OFFSET      0x00
+#define MEMCONTROL_OFFSET      0x04
+#define MEMCONFIG0_OFFSET      0x08
+#define MEMCONFIG1_OFFSET      0x0c
+#define DIRECTCMD_OFFSET       0x10
+#define PRECHCONFIG_OFFSET     0x14
+#define PHYCONTROL0_OFFSET     0x18
+#define PHYCONTROL1_OFFSET     0x1c
+#define PHYCONTROL2_OFFSET     0x20
+#define PWRDNCONFIG_OFFSET     0x28
+#define TIMINGAREF_OFFSET      0x30
+#define TIMINGROW_OFFSET       0x34
+#define TIMINGDATA_OFFSET      0x38
+#define TIMINGPOWER_OFFSET     0x3c
+#define PHYSTATUS0_OFFSET      0x40
+#define PHYSTATUS1_OFFSET      0x44
+#define CHIP0STATUS_OFFSET     0x48
+#define CHIP1STATUS_OFFSET     0x4c
+#define AREFSTATUS_OFFSET      0x50
+#define MRSTATUS_OFFSET                0x54
+#define PHYTEST0_OFFSET                0x58
+#define PHYTEST1_OFFSET                0x5c
+
+#endif
diff --git a/include/asm-arm/arch-s5p64xx/mmc.h b/include/asm-arm/arch-s5p64xx/mmc.h
new file mode 100644 (file)
index 0000000..4efefba
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * (C) Copyright 2009 SAMSUNG Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __ASM_ARCH_MMC_H_
+#define __ASM_ARCH_MMC_H_
+
+#define S5PC100_MMC_BASE       0xED800000
+#define S5PC110_MMC_BASE       0xEB000000
+
+#ifndef __ASSEMBLY__
+struct s5pc1xx_mmc {
+       unsigned long   sysad;
+       unsigned short  blksize;
+       unsigned short  blkcnt;
+       unsigned long   argument;
+       unsigned short  trnmod;
+       unsigned short  cmdreg;
+       unsigned long   rspreg0;
+       unsigned long   rspreg1;
+       unsigned long   rspreg2;
+       unsigned long   rspreg3;
+       unsigned long   bdata;
+       unsigned long   prnsts;
+       unsigned char   hostctl;
+       unsigned char   pwrcon;
+       unsigned char   blkgap;
+       unsigned char   wakcon;
+       unsigned short  clkcon;
+       unsigned char   timeoutcon;
+       unsigned char   swrst;
+       unsigned short  norintsts;
+       unsigned short  errintsts;
+       unsigned short  norintstsen;
+       unsigned short  errintstsen;
+       unsigned short  norintsigen;
+       unsigned short  errintsigen;
+       unsigned short  acmd12errsts;
+       unsigned char   res1[2];
+       unsigned long   capareg;
+       unsigned char   res2[4];
+       unsigned long   maxcurr;
+       unsigned char   res3[0x34];
+       unsigned long   control2;
+       unsigned long   control3;
+       unsigned long   control4;
+       unsigned char   res4[0x6e];
+       unsigned short  hcver;
+       unsigned char   res5[0xFFF00];
+};
+
+struct mmc_host {
+       struct s5pc1xx_mmc *reg;
+       unsigned int version;   /* SDHCI spec. version */
+       unsigned int clock;     /* Current clock (MHz) */
+};
+
+int s5pc1xx_mmc_init(int dev_index);
+
+#endif /* __ASSEMBLY__ */
+#endif
diff --git a/include/asm-arm/arch-s5p64xx/power.h b/include/asm-arm/arch-s5p64xx/power.h
new file mode 100644 (file)
index 0000000..6ade0f4
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARM_ARCH_POWER_H_
+#define __ASM_ARM_ARCH_POWER_H_
+
+/*
+ * Power control
+ */
+#define S5P6442_RST_STAT               0xE010A000
+#define S5P6442_SLEEP_WAKEUP           (1 << 16)
+#define S5P6442_OSC_CON                        0xE0108000
+#define S5P6442_PWR_CFG                        0xE010C000
+#define S5P6442_CFG_STANDBYWFI_MASK    (0x3 << 8)
+#define S5P6442_CFG_STANDBYWFI_IGNORE  (0x0 << 8)
+#define S5P6442_CFG_STANDBYWFI_IDLE    (0x1 << 8)
+#define S5P6442_CFG_STANDBYWFI_STOP    (0x2 << 8)
+#define S5P6442_CFG_STANDBYWFI_SLEEP   (0x3 << 8)
+#define S5P6442_EINT_WAKEUP_MASK       0xE010C004
+#define S5P6442_WAKEUP_MASK            0xE010C008
+#define S5P6442_PWR_MODE               0xE010C00C
+#define S5P6442_PWR_MODE_SLEEP         (1 << 2)
+#define S5P6442_NORMAL_CFG             0xE010C010
+#define S5P6442_IDLE_CFG               0xE010C020
+#define S5P6442_STOP_CFG               0xE010C030
+#define S5P6442_STOP_MEM_CFG           0xE010C034
+#define S5P6442_SLEEP_CFG              0xE010C040
+#define S5P6442_OSC_FREQ               0xE010C100
+#define S5P6442_OSC_STABLE             0xE010C104
+#define S5P6442_PWR_STABLE             0xE010C108
+#define S5P6442_MTC_STABLE             0xE010C110
+#define S5P6442_CLAMP_STABLE           0xE010C114
+#define S5P6442_WAKEUP_STAT            0xE010C200
+#define S5P6442_OTHERS                 0xE010E000
+#define S5P6442_OTHERS_SYSCON_INT_DISABLE      (1 << 0)
+#define S5P6442_MIE_CONTROL            0xE010E800
+#define S5P6442_HDMI_CONTROL           0xE010E804
+#define S5P6442_USB_PHY_CON            0xE010E80C
+#define S5P6442_DAC_CONTROL            0xE010E810
+#define S5P6442_MIPI_DPHY_CONTROL      0xE010E814
+#define S5P6442_ADC_CONTROL            0xE010E818
+#define S5P6442_PS_HOLD_CONTROL                0xE010E81C
+#define S5P6442_PS_HOLD_DIR_OUTPUT     (1 << 9)
+#define S5P6442_PS_HOLD_DIR_INPUT      (0 << 9)
+#define S5P6442_PS_HOLD_DATA_HIGH      (1 << 8)
+#define S5P6442_PS_HOLD_DATA_LOW       (0 << 8)
+#define S5P6442_PS_HOLD_OUT_EN         (1 << 0)
+#define S5P6442_INFORM0                        0xE010F000
+#define S5P6442_INFORM1                        0xE010F004
+#define S5P6442_INFORM2                        0xE010F008
+#define S5P6442_INFORM3                        0xE010F00C
+#define S5P6442_INFORM4                        0xE010F010
+#define S5P6442_INFORM5                        0xE010F014
+#define S5P6442_INFORM6                        0xE010F018
+#define S5P6442_INFORM7                        0xE010F01C
+
+#endif
diff --git a/include/asm-arm/arch-s5p64xx/pwm.h b/include/asm-arm/arch-s5p64xx/pwm.h
new file mode 100644 (file)
index 0000000..13b1bb0
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARM_ARCH_PWM_H_
+#define __ASM_ARM_ARCH_PWM_H_
+
+/* PWM timer addressing */
+#define S5P6442_TIMER_BASE     S5P6442_PWMTIMER_BASE
+
+/* Interval mode(Auto Reload) of PWM Timer 4 */
+#define S5P64XX_TCON4_AUTO_RELOAD      (1 << 22)
+/* Update TCNTB4 */
+#define S5P64XX_TCON4_UPDATE           (1 << 21)
+/* start bit of PWM Timer 4 */
+#define S5P64XX_TCON4_START            (1 << 20)
+
+#ifndef __ASSEMBLY__
+struct s5p64xx_timer {
+       unsigned int    tcfg0;
+       unsigned int    tcfg1;
+       unsigned int    tcon;
+       unsigned int    tcntb0;
+       unsigned int    tcmpb0;
+       unsigned int    tcnto0;
+       unsigned int    tcntb1;
+       unsigned int    tcmpb1;
+       unsigned int    tcnto1;
+       unsigned int    tcntb2;
+       unsigned int    tcmpb2;
+       unsigned int    tcnto2;
+       unsigned int    tcntb3;
+       unsigned int    res1;
+       unsigned int    tcnto3;
+       unsigned int    tcntb4;
+       unsigned int    tcnto4;
+       unsigned int    tintcstat;
+};
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/include/asm-arm/arch-s5p64xx/regs-fb.h b/include/asm-arm/arch-s5p64xx/regs-fb.h
new file mode 100644 (file)
index 0000000..800bb50
--- /dev/null
@@ -0,0 +1,388 @@
+/* linux/asm/arch/regs-fb.h
+ *
+ * Register definition file for Samsung Display Controller (FIMD) driver
+ *
+ * Jinsung Yang, Copyright (c) 2009 Samsung Electronics
+ *     http://www.samsungsemi.com/
+ *
+ * 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 _REGS_FB_H
+#define _REGS_FB_H
+
+#define S5P_LCDREG(x)          (x)
+#define S5P_WINCON(x)          S5P_LCDREG(0x0020 + (x * 0x04))
+#define S5P_VIDOSD_A(x)                S5P_LCDREG(0x0040 + (x * 0x10))
+#define S5P_VIDOSD_B(x)                S5P_LCDREG(0x0044 + (x * 0x10))
+#define S5P_VIDOSD_C(x)                S5P_LCDREG(0x0048 + (x * 0x10))
+#define S5P_VIDOSD_D(x)                S5P_LCDREG(0x004C + (x * 0x10))
+#define S5P_VIDADDR_START0(x)  S5P_LCDREG(0x00A0 + (x * 0x08))
+#define S5P_VIDADDR_START1(x)  S5P_LCDREG(0x00A4 + (x * 0x08))
+#define S5P_VIDADDR_END0(x)    S5P_LCDREG(0x00D0 + (x * 0x08))
+#define S5P_VIDADDR_END1(x)    S5P_LCDREG(0x00D4 + (x * 0x08))
+#define S5P_VIDADDR_SIZE(x)    S5P_LCDREG(0x0100 + (x * 0x04))
+#define S5P_KEYCON(x)          S5P_LCDREG(0x0140 + ((x - 1) * 0x08))
+#define S5P_KEYVAL(x)          S5P_LCDREG(0x0144 + ((x - 1) * 0x08))
+
+/*
+ * Register Map
+*/
+#define S5P_VIDCON0            S5P_LCDREG(0x0000)      /* Video control 0 */
+#define S5P_VIDCON1            S5P_LCDREG(0x0004)      /* Video control 1 */
+#define S5P_VIDCON2            S5P_LCDREG(0x0008)      /* Video control 2 */
+#define S5P_PRTCON             S5P_LCDREG(0x000C)      /* Protect control */
+
+#define S5P_VIDTCON0           S5P_LCDREG(0x0010)      /* Video time control 0 */
+#define S5P_VIDTCON1           S5P_LCDREG(0x0014)      /* Video time control 1 */
+#define S5P_VIDTCON2           S5P_LCDREG(0x0018)      /* Video time control 2 */
+
+#define S5P_WINCON0            S5P_LCDREG(0x0020)      /* Window control 0 */
+#define S5P_WINCON1            S5P_LCDREG(0x0024)      /* Window control 1 */
+#define S5P_WINCON2            S5P_LCDREG(0x0028)      /* Window control 2 */
+#define S5P_WINCON3            S5P_LCDREG(0x002C)      /* Window control 3 */
+#define S5P_WINCON4            S5P_LCDREG(0x0030)      /* Window control 4 */
+#define S5P_WINSHMAP           S5P_LCDREG(0x0034)      /* Window Shodow control */
+#define S5P_WINCHMAP2          S5P_LCDREG(0x003C)      /* Channel mapping control register */
+
+#define S5P_VIDOSD0A           S5P_LCDREG(0x0040)      /* Video Window 0 position control */
+#define S5P_VIDOSD0B           S5P_LCDREG(0x0044)      /* Video Window 0 position control1 */
+#define S5P_VIDOSD0C           S5P_LCDREG(0x0048)      /* Video Window 0 position control */
+
+#define S5P_VIDOSD1A           S5P_LCDREG(0x0050)      /* Video Window 1 position control */
+#define S5P_VIDOSD1B           S5P_LCDREG(0x0054)      /* Video Window 1 position control */
+#define S5P_VIDOSD1C           S5P_LCDREG(0x0058)      /* Video Window 1 position control */
+#define S5P_VIDOSD1D           S5P_LCDREG(0x005C)      /* Video Window 1 position control */
+
+#define S5P_VIDOSD2A           S5P_LCDREG(0x0060)      /* Video Window 2 position control */
+#define S5P_VIDOSD2B           S5P_LCDREG(0x0064)      /* Video Window 2 position control */
+#define S5P_VIDOSD2C           S5P_LCDREG(0x0068)      /* Video Window 2 position control */
+#define S5P_VIDOSD2D           S5P_LCDREG(0x006C)      /* Video Window 2 position control */
+
+#define S5P_VIDOSD3A           S5P_LCDREG(0x0070)      /* Video Window 3 position control */
+#define S5P_VIDOSD3B           S5P_LCDREG(0x0074)      /* Video Window 3 position control */
+#define S5P_VIDOSD3C           S5P_LCDREG(0x0078)      /* Video Window 3 position control */
+
+#define S5P_VIDOSD4A           S5P_LCDREG(0x0080)      /* Video Window 4 position control */
+#define S5P_VIDOSD4B           S5P_LCDREG(0x0084)      /* Video Window 4 position control */
+#define S5P_VIDOSD4C           S5P_LCDREG(0x0088)      /* Video Window 4 position control */
+
+#define S5P_VIDW00ADD0B0       S5P_LCDREG(0x00A0)      /* Window 0 buffer start address, buffer 0 */
+#define S5P_VIDW00ADD0B1       S5P_LCDREG(0x00A4)      /* Window 0 buffer start address, buffer 1 */
+#define S5P_VIDW01ADD0B0       S5P_LCDREG(0x00A8)      /* Window 1 buffer start address, buffer 0 */
+#define S5P_VIDW01ADD0B1       S5P_LCDREG(0x00AC)      /* Window 1 buffer start address, buffer 1 */
+#define S5P_VIDW02ADD0         S5P_LCDREG(0x00B0)      /* Window 2 buffer start address, buffer 0 */
+#define S5P_VIDW03ADD0         S5P_LCDREG(0x00B8)      /* Window 3 buffer start address, buffer 0 */
+#define S5P_VIDW04ADD0         S5P_LCDREG(0x00C0)      /* Window 4 buffer start address, buffer 0 */
+#define S5P_VIDW00ADD1B0       S5P_LCDREG(0x00D0)      /* Window 0 buffer end address, buffer 0 */
+#define S5P_VIDW00ADD1B1       S5P_LCDREG(0x00D4)      /* Window 0 buffer end address, buffer 1 */
+#define S5P_VIDW01ADD1B0       S5P_LCDREG(0x00D8)      /* Window 1 buffer end address, buffer 0 */
+#define S5P_VIDW01ADD1B1       S5P_LCDREG(0x00DC)      /* Window 1 buffer end address, buffer 1 */
+#define S5P_VIDW02ADD1         S5P_LCDREG(0x00E0)      /* Window 2 buffer end address */
+#define S5P_VIDW03ADD1         S5P_LCDREG(0x00E8)      /* Window 3 buffer end address */
+#define S5P_VIDW04ADD1         S5P_LCDREG(0x00F0)      /* Window 4 buffer end address */
+#define S5P_VIDW00ADD2         S5P_LCDREG(0x0100)      /* Window 0 buffer size */
+#define S5P_VIDW01ADD2         S5P_LCDREG(0x0104)      /* Window 1 buffer size */
+#define S5P_VIDW02ADD2         S5P_LCDREG(0x0108)      /* Window 2 buffer size */
+#define S5P_VIDW03ADD2         S5P_LCDREG(0x010C)      /* Window 3 buffer size */
+#define S5P_VIDW04ADD2         S5P_LCDREG(0x0110)      /* Window 4 buffer size */
+
+#define S5P_VP1TCON0           S5P_LCDREG(0x0118)      /* VP1 interface timing control 0 */
+#define S5P_VP1TCON1           S5P_LCDREG(0x011C)      /* VP1 interface timing control 1 */
+
+#define S5P_VIDINTCON0         S5P_LCDREG(0x0130)      /* Indicate the Video interrupt control */
+#define S5P_VIDINTCON1         S5P_LCDREG(0x0134)      /* Video Interrupt Pending */
+
+#define S5P_W1KEYCON0          S5P_LCDREG(0x0140)      /* Color key control */
+#define S5P_W1KEYCON1          S5P_LCDREG(0x0144)      /* Color key value (transparent value) */
+#define S5P_W2KEYCON0          S5P_LCDREG(0x0148)      /* Color key control */
+#define S5P_W2KEYCON1          S5P_LCDREG(0x014C)      /* Color key value (transparent value) */
+#define S5P_W3KEYCON0          S5P_LCDREG(0x0150)      /* Color key control */
+#define S5P_W3KEYCON1          S5P_LCDREG(0x0154)      /* Color key value (transparent value) */
+#define S5P_W4KEYCON0          S5P_LCDREG(0x0158)      /* Color key control */
+#define S5P_W4KEYCON1          S5P_LCDREG(0x015C)      /* Color key value (transparent value) */
+
+#define S5P_W1KEYALPHA         S5P_LCDREG(0x0160)      /* Color key alpha value */
+#define S5P_W2KEYALPHA         S5P_LCDREG(0x0164)      /* Color key alpha value */
+#define S5P_W3KEYALPHA         S5P_LCDREG(0x0168)      /* Color key alpha value */
+#define S5P_W4KEYALPHA         S5P_LCDREG(0x016C)      /* Color key alpha value */
+
+#define S5P_DITHMODE           S5P_LCDREG(0x0170)      /* Dithering mode */
+
+#define S5P_WIN0MAP            S5P_LCDREG(0x0180)      /* Window color control */
+#define S5P_WIN1MAP            S5P_LCDREG(0x0184)      /* Window color control */
+#define S5P_WIN2MAP            S5P_LCDREG(0x0188)      /* Window color control */
+#define S5P_WIN3MAP            S5P_LCDREG(0x018C)      /* Window color control */
+#define S5P_WIN4MAP            S5P_LCDREG(0x0190)      /* Window color control */
+
+#define S5P_WPALCON_H          S5P_LCDREG(0x019C)      /* Window Palette control */
+#define S5P_WPALCON_L          S5P_LCDREG(0x01A0)      /* Window Palette control */
+
+#define S5P_VIDW0ALPHA0                S5P_LCDREG(0x0200)      /* Window 0 alpha value 0 */
+#define S5P_VIDW0ALPHA1                S5P_LCDREG(0x0204)      /* Window 0 alpha value 1 */
+#define S5P_VIDW1ALPHA0                S5P_LCDREG(0x0208)      /* Window 1 alpha value 0 */
+#define S5P_VIDW1ALPHA1                S5P_LCDREG(0x020C)      /* Window 1 alpha value 1 */
+#define S5P_VIDW2ALPHA0                S5P_LCDREG(0x0210)      /* Window 2 alpha value 0 */
+#define S5P_VIDW2ALPHA1                S5P_LCDREG(0x0214)      /* Window 2 alpha value 1 */
+#define S5P_VIDW3ALPHA0                S5P_LCDREG(0x0218)      /* Window 3 alpha value 0 */
+#define S5P_VIDW3ALPHA1                S5P_LCDREG(0x021C)      /* Window 3 alpha value 1 */
+#define S5P_VIDW4ALPHA0                S5P_LCDREG(0x0220)      /* Window 4 alpha value 0 */
+#define S5P_VIDW4ALPHA1                S5P_LCDREG(0x0224)      /* Window 4 alpha value 1 */
+
+#define S5P_BLENDEQ1           S5P_LCDREG(0x0244)      /* Window 1 blending equation control */
+#define S5P_BLENDEQ2           S5P_LCDREG(0x0248)      /* Window 2 blending equation control */
+#define S5P_BLENDEQ3           S5P_LCDREG(0x024C)      /* Window 3 blending equation control */
+#define S5P_BLENDEQ4           S5P_LCDREG(0x0250)      /* Window 4 blending equation control */
+#define S5P_BLENDCON           S5P_LCDREG(0x0260)      /* Blending control */
+#define S5P_DUALRGB                    S5P_LCDREG(0x027C)      /* DUALRGB Interface Setting Register */
+
+/*
+ * Bit Definitions
+*/
+
+/* VIDCON0 */
+#define S5P_VIDCON0_DSI_DISABLE                        (0 << 30)
+#define S5P_VIDCON0_DSI_ENABLE                 (1 << 30)
+#define S5P_VIDCON0_SCAN_PROGRESSIVE           (0 << 29)
+#define S5P_VIDCON0_SCAN_INTERLACE             (1 << 29)
+#define S5P_VIDCON0_SCAN_MASK                  (1 << 29)
+#define S5P_VIDCON0_VIDOUT_RGB                 (0 << 26)
+#define S5P_VIDCON0_VIDOUT_ITU                 (1 << 26)
+#define S5P_VIDCON0_VIDOUT_I80LDI0             (2 << 26)
+#define S5P_VIDCON0_VIDOUT_I80LDI1             (3 << 26)
+#define S5P_VIDCON0_VIDOUT_MASK                        (3 << 26)
+#define S5P_VIDCON0_PNRMODE_RGB_P              (0 << 17)
+#define S5P_VIDCON0_PNRMODE_BGR_P              (1 << 17)
+#define S5P_VIDCON0_PNRMODE_RGB_S              (2 << 17)
+#define S5P_VIDCON0_PNRMODE_BGR_S              (3 << 17)
+#define S5P_VIDCON0_PNRMODE_MASK               (3 << 17)
+#define S5P_VIDCON0_PNRMODE_SHIFT              (17)
+#define S5P_VIDCON0_CLKVALUP_ALWAYS            (0 << 16)
+#define S5P_VIDCON0_CLKVALUP_START_FRAME       (1 << 16)
+#define S5P_VIDCON0_CLKVALUP_MASK              (1 << 16)
+#define S5P_VIDCON0_CLKVAL_F(x)                        (((x) & 0xff) << 6)
+#define S5P_VIDCON0_VCLKEN_NORMAL              (0 << 5)
+#define S5P_VIDCON0_VCLKEN_FREERUN             (1 << 5)
+#define S5P_VIDCON0_VCLKEN_MASK                        (1 << 5)
+#define S5P_VIDCON0_CLKDIR_DIRECTED            (0 << 4)
+#define S5P_VIDCON0_CLKDIR_DIVIDED             (1 << 4)
+#define S5P_VIDCON0_CLKDIR_MASK                        (1 << 4)
+#define S5P_VIDCON0_CLKSEL_HCLK                        (0 << 2)
+#define S5P_VIDCON0_CLKSEL_SCLK                        (1 << 2)
+#define S5P_VIDCON0_CLKSEL_MASK                        (1 << 2)
+#define S5P_VIDCON0_ENVID_ENABLE               (1 << 1)
+#define S5P_VIDCON0_ENVID_DISABLE              (0 << 1)
+#define S5P_VIDCON0_ENVID_F_ENABLE             (1 << 0)
+#define S5P_VIDCON0_ENVID_F_DISABLE            (0 << 0)
+
+/* VIDCON1 */
+#define S5P_VIDCON1_IVCLK_FALLING_EDGE         (0 << 7)
+#define S5P_VIDCON1_IVCLK_RISING_EDGE          (1 << 7)
+#define S5P_VIDCON1_IHSYNC_NORMAL              (0 << 6)
+#define S5P_VIDCON1_IHSYNC_INVERT              (1 << 6)
+#define S5P_VIDCON1_IVSYNC_NORMAL              (0 << 5)
+#define S5P_VIDCON1_IVSYNC_INVERT              (1 << 5)
+#define S5P_VIDCON1_IVDEN_NORMAL               (0 << 4)
+#define S5P_VIDCON1_IVDEN_INVERT               (1 << 4)
+
+/* VIDCON2 */
+#define S5P_VIDCON2_EN601_DISABLE              (0 << 23)
+#define S5P_VIDCON2_EN601_ENABLE               (1 << 23)
+#define S5P_VIDCON2_EN601_MASK                 (1 << 23)
+#define S5P_VIDCON2_ORGYUV_YCBCR               (0 << 8)
+#define S5P_VIDCON2_ORGYUV_CBCRY               (1 << 8)
+#define S5P_VIDCON2_ORGYUV_MASK                        (1 << 8)
+#define S5P_VIDCON2_YUVORD_CBCR                        (0 << 7)
+#define S5P_VIDCON2_YUVORD_CRCB                        (1 << 7)
+#define S5P_VIDCON2_YUVORD_MASK                        (1 << 7)
+
+/* PRTCON */
+#define S5P_PRTCON_UPDATABLE                   (0 << 11)
+#define S5P_PRTCON_PROTECT                     (1 << 11)
+
+/* VIDTCON0 */
+#define S5P_VIDTCON0_VBPDE(x)                  (((x) & 0xff) << 24)
+#define S5P_VIDTCON0_VBPD(x)                   (((x) & 0xff) << 16)
+#define S5P_VIDTCON0_VFPD(x)                   (((x) & 0xff) << 8)
+#define S5P_VIDTCON0_VSPW(x)                   (((x) & 0xff) << 0)
+
+/* VIDTCON1 */
+#define S5P_VIDTCON1_VFPDE(x)                  (((x) & 0xff) << 24)
+#define S5P_VIDTCON1_HBPD(x)                   (((x) & 0xff) << 16)
+#define S5P_VIDTCON1_HFPD(x)                   (((x) & 0xff) << 8)
+#define S5P_VIDTCON1_HSPW(x)                   (((x) & 0xff) << 0)
+
+/* VIDTCON2 */
+#define S5P_VIDTCON2_LINEVAL(x)                        (((x) & 0x7ff) << 11)
+#define S5P_VIDTCON2_HOZVAL(x)                 (((x) & 0x7ff) << 0)
+
+/* Window 0~4 Control - WINCONx */
+#define S5P_WINCON_DATAPATH_DMA                        (0 << 22)
+#define S5P_WINCON_DATAPATH_LOCAL              (1 << 22)
+#define S5P_WINCON_DATAPATH_MASK               (1 << 22)
+#define S5P_WINCON_BUFSEL_0                    (0 << 20)
+#define S5P_WINCON_BUFSEL_1                    (1 << 20)
+#define S5P_WINCON_BUFSEL_MASK                 (1 << 20)
+#define S5P_WINCON_BUFSEL_SHIFT                        (20)
+#define S5P_WINCON_BUFAUTO_DISABLE             (0 << 19)
+#define S5P_WINCON_BUFAUTO_ENABLE              (1 << 19)
+#define S5P_WINCON_BUFAUTO_MASK                        (1 << 19)
+#define S5P_WINCON_BITSWP_DISABLE              (0 << 18)
+#define S5P_WINCON_BITSWP_ENABLE               (1 << 18)
+#define S5P_WINCON_BITSWP_SHIFT                        (18)
+#define S5P_WINCON_BYTESWP_DISABLE             (0 << 17)
+#define S5P_WINCON_BYTESWP_ENABLE              (1 << 17)
+#define S5P_WINCON_BYTESWP_SHIFT               (17)
+#define S5P_WINCON_HAWSWP_DISABLE              (0 << 16)
+#define S5P_WINCON_HAWSWP_ENABLE               (1 << 16)
+#define S5P_WINCON_HAWSWP_SHIFT                        (16)
+#define S5P_WINCON_WSWP_DISABLE                        (0 << 15)
+#define S5P_WINCON_WSWP_ENABLE                 (1 << 15)
+#define S5P_WINCON_WSWP_SHIFT                  (15)
+#define S5P_WINCON_INRGB_RGB                   (0 << 13)
+#define S5P_WINCON_INRGB_YUV                   (1 << 13)
+#define S5P_WINCON_INRGB_MASK                  (1 << 13)
+#define S5P_WINCON_BURSTLEN_16WORD             (0 << 9)
+#define S5P_WINCON_BURSTLEN_8WORD              (1 << 9)
+#define S5P_WINCON_BURSTLEN_4WORD              (2 << 9)
+#define S5P_WINCON_BURSTLEN_MASK               (3 << 9)
+#define S5P_WINCON_ALPHA_MULTI_DISABLE         (0 << 7)
+#define S5P_WINCON_ALPHA_MULTI_ENABLE          (1 << 7)
+#define S5P_WINCON_BLD_PLANE                   (0 << 6)
+#define S5P_WINCON_BLD_PIXEL                   (1 << 6)
+#define S5P_WINCON_BLD_MASK                    (1 << 6)
+#define S5P_WINCON_BPPMODE_1BPP                        (0 << 2)
+#define S5P_WINCON_BPPMODE_2BPP                        (1 << 2)
+#define S5P_WINCON_BPPMODE_4BPP                        (2 << 2)
+#define S5P_WINCON_BPPMODE_8BPP_PAL            (3 << 2)
+#define S5P_WINCON_BPPMODE_8BPP                        (4 << 2)
+#define S5P_WINCON_BPPMODE_16BPP_565           (5 << 2)
+#define S5P_WINCON_BPPMODE_16BPP_A555          (6 << 2)
+#define S5P_WINCON_BPPMODE_18BPP_666           (8 << 2)
+#define S5P_WINCON_BPPMODE_18BPP_A665          (9 << 2)
+#define S5P_WINCON_BPPMODE_24BPP_888           (0xb << 2)
+#define S5P_WINCON_BPPMODE_24BPP_A887          (0xc << 2)
+#define S5P_WINCON_BPPMODE_32BPP               (0xd << 2)
+#define S5P_WINCON_BPPMODE_16BPP_A444          (0xe << 2)
+#define S5P_WINCON_BPPMODE_15BPP_555           (0xf << 2)
+#define S5P_WINCON_BPPMODE_MASK                        (0xf << 2)
+#define S5P_WINCON_BPPMODE_SHIFT               (2)
+#define S5P_WINCON_ALPHA0_SEL                  (0 << 1)
+#define S5P_WINCON_ALPHA1_SEL                  (1 << 1)
+#define S5P_WINCON_ALPHA_SEL_MASK              (1 << 1)
+#define S5P_WINCON_ENWIN_DISABLE               (0 << 0)
+#define S5P_WINCON_ENWIN_ENABLE                        (1 << 0)
+
+/* WINSHMAP */
+#define S5P_WINSHMAP_CH_ENABLE(x)              (1 << x)
+#define S5P_WINSHMAP_CH_DISABLE(x)             (0 << x)
+#define S5P_WINSHMAP_CH_LOCAL_ENABLE(x)                (1 << (x + 5))
+#define S5P_WINSHMAP_CH_LOCAL_DISABLE(x)       (0 << (x + 5))
+
+/* WINCON1 special */
+#define S5P_WINCON1_VP_DISABLE                 (0 << 24)
+#define S5P_WINCON1_VP_ENABLE                  (1 << 24)
+#define S5P_WINCON1_LOCALSEL_FIMC1             (0 << 23)
+#define S5P_WINCON1_LOCALSEL_VP                        (1 << 23)
+#define S5P_WINCON1_LOCALSEL_MASK              (1 << 23)
+
+/* VIDOSDxA, VIDOSDxB */
+#define S5P_VIDOSD_LEFT_X(x)                   (((x) & 0x7ff) << 11)
+#define S5P_VIDOSD_TOP_Y(x)                    (((x) & 0x7ff) << 0)
+#define S5P_VIDOSD_RIGHT_X(x)                  (((x) & 0x7ff) << 11)
+#define S5P_VIDOSD_BOTTOM_Y(x)                 (((x) & 0x7ff) << 0)
+
+/* VIDOSD0C, VIDOSDxD */
+#define S5P_VIDOSD_SIZE(x)                     (((x) & 0xffffff) << 0)
+
+/* VIDOSDxC (1~4) */
+#define S5P_VIDOSD_ALPHA0_R(x)                 (((x) & 0xf) << 20)
+#define S5P_VIDOSD_ALPHA0_G(x)                 (((x) & 0xf) << 16)
+#define S5P_VIDOSD_ALPHA0_B(x)                 (((x) & 0xf) << 12)
+#define S5P_VIDOSD_ALPHA1_R(x)                 (((x) & 0xf) << 8)
+#define S5P_VIDOSD_ALPHA1_G(x)                 (((x) & 0xf) << 4)
+#define S5P_VIDOSD_ALPHA1_B(x)                 (((x) & 0xf) << 0)
+#define S5P_VIDOSD_ALPHA0_SHIFT                        (12)
+#define S5P_VIDOSD_ALPHA1_SHIFT                        (0)
+
+/* Start Address */
+#define S5P_VIDADDR_START_VBANK(x)             (((x) & 0xff) << 24)
+#define S5P_VIDADDR_START_VBASEU(x)            (((x) & 0xffffff) << 0)
+
+/* End Address */
+#define S5P_VIDADDR_END_VBASEL(x)              (((x) & 0xffffff) << 0)
+
+/* Buffer Size */
+#define S5P_VIDADDR_OFFSIZE(x)                 (((x) & 0x1fff) << 13)
+#define S5P_VIDADDR_PAGEWIDTH(x)               (((x) & 0x1fff) << 0)
+
+/* VIDINTCON0 */
+#define S5P_VIDINTCON0_SYSMAINCON_DISABLE      (0 << 19)
+#define S5P_VIDINTCON0_SYSMAINCON_ENABLE       (1 << 19)
+#define S5P_VIDINTCON0_SYSSUBCON_DISABLE       (0 << 18)
+#define S5P_VIDINTCON0_SYSSUBCON_ENABLE                (1 << 18)
+#define S5P_VIDINTCON0_SYSIFDONE_DISABLE       (0 << 17)
+#define S5P_VIDINTCON0_SYSIFDONE_ENABLE                (1 << 17)
+#define S5P_VIDINTCON0_FRAMESEL0_BACK          (0 << 15)
+#define S5P_VIDINTCON0_FRAMESEL0_VSYNC         (1 << 15)
+#define S5P_VIDINTCON0_FRAMESEL0_ACTIVE                (2 << 15)
+#define S5P_VIDINTCON0_FRAMESEL0_FRONT         (3 << 15)
+#define S5P_VIDINTCON0_FRAMESEL0_MASK          (3 << 15)
+#define S5P_VIDINTCON0_FRAMESEL1_NONE          (0 << 13)
+#define S5P_VIDINTCON0_FRAMESEL1_BACK          (1 << 13)
+#define S5P_VIDINTCON0_FRAMESEL1_VSYNC         (2 << 13)
+#define S5P_VIDINTCON0_FRAMESEL1_FRONT         (3 << 13)
+#define S5P_VIDINTCON0_INTFRMEN_DISABLE                (0 << 12)
+#define S5P_VIDINTCON0_INTFRMEN_ENABLE         (1 << 12)
+#define S5P_VIDINTCON0_FIFOSEL_WIN4            (1 << 11)
+#define S5P_VIDINTCON0_FIFOSEL_WIN3            (1 << 10)
+#define S5P_VIDINTCON0_FIFOSEL_WIN2            (1 << 9)
+#define S5P_VIDINTCON0_FIFOSEL_WIN1            (1 << 6)
+#define S5P_VIDINTCON0_FIFOSEL_WIN0            (1 << 5)
+#define S5P_VIDINTCON0_FIFOSEL_ALL             (0x73 << 5)
+#define S5P_VIDINTCON0_FIFOSEL_MASK            (0x73 << 5)
+#define S5P_VIDINTCON0_FIFOLEVEL_25            (0 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_50            (1 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_75            (2 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_EMPTY         (3 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_FULL          (4 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_MASK          (7 << 2)
+#define S5P_VIDINTCON0_INTFIFO_DISABLE         (0 << 1)
+#define S5P_VIDINTCON0_INTFIFO_ENABLE          (1 << 1)
+#define S5P_VIDINTCON0_INT_DISABLE             (0 << 0)
+#define S5P_VIDINTCON0_INT_ENABLE              (1 << 0)
+#define S5P_VIDINTCON0_INT_MASK                        (1 << 0)
+
+/* VIDINTCON1 */
+#define S5P_VIDINTCON1_INTVPPEND               (1 << 5)
+#define S5P_VIDINTCON1_INTI80PEND              (1 << 2)
+#define S5P_VIDINTCON1_INTFRMPEND              (1 << 1)
+#define S5P_VIDINTCON1_INTFIFOPEND             (1 << 0)
+
+/* WxKEYCON0 (1~4) */
+#define S5P_KEYCON0_KEYBLEN_DISABLE            (0 << 26)
+#define S5P_KEYCON0_KEYBLEN_ENABLE             (1 << 26)
+#define S5P_KEYCON0_KEY_DISABLE                (0 << 25)
+#define S5P_KEYCON0_KEY_ENABLE                 (1 << 25)
+#define S5P_KEYCON0_DIRCON_MATCH_FG            (0 << 24)
+#define S5P_KEYCON0_DIRCON_MATCH_BG            (1 << 24)
+#define S5P_KEYCON0_COMPKEY(x)                 (((x) & 0xffffff) << 0)
+
+/* WxKEYCON1 (1~4) */
+#define S5P_KEYCON1_COLVAL(x)                  (((x) & 0xffffff) << 0)
+
+/* DUALRGB */
+#define S5P_DUALRGB_BYPASS_SINGLE              (0x00 << 0)
+#define S5P_DUALRGB_BYPASS_DUAL                        (0x01 << 0)
+#define S5P_DUALRGB_MIE_DUAL                   (0x10 << 0)
+#define S5P_DUALRGB_MIE_SINGLE                 (0x11 << 0)
+#define S5P_DUALRGB_LINESPLIT                  (0x0 << 2)
+#define S5P_DUALRGB_FRAMESPLIT                 (0x1 << 2)
+#define S5P_DUALRGB_SUB_CNT(x)                 ((x & 0xfff) << 4)
+#define S5P_DUALRGB_VDEN_EN_DISABLE            (0x0 << 16)
+#define S5P_DUALRGB_VDEN_EN_ENABLE             (0x1 << 16)
+#define S5P_DUALRGB_MAIN_CNT(x)                        ((x & 0xfff) << 18)
+
+#endif /* _REGS_FB_H */
diff --git a/include/asm-arm/arch-s5p64xx/sys_proto.h b/include/asm-arm/arch-s5p64xx/sys_proto.h
new file mode 100644 (file)
index 0000000..3078aaf
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2009 Samsung Electrnoics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SYS_PROTO_H_
+#define _SYS_PROTO_H_
+
+u32 get_device_type(void);
+void invalidate_dcache(u32);
+void l2_cache_disable(void);
+void l2_cache_enable(void);
+
+#endif
diff --git a/include/asm-arm/arch-s5p64xx/uart.h b/include/asm-arm/arch-s5p64xx/uart.h
new file mode 100644 (file)
index 0000000..122bf0c
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_UART_H_
+#define __ASM_ARCH_UART_H_
+
+#ifndef __ASSEMBLY__
+struct s5pc1xx_uart {
+       unsigned int    ulcon;
+       unsigned int    ucon;
+       unsigned int    ufcon;
+       unsigned int    umcon;
+       unsigned int    utrstat;
+       unsigned int    uerstat;
+       unsigned int    ufstat;
+       unsigned int    umstat;
+       unsigned char   utxh;
+       unsigned char   res1[3];
+       unsigned char   urxh;
+       unsigned char   res2[3];
+       unsigned int    ubrdiv;
+       unsigned short  udivslot;
+       unsigned char   res3[2];
+       unsigned char   res4[0x3d0];
+};
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/include/asm-arm/arch-s5p64xx/usb-hs-otg.h b/include/asm-arm/arch-s5p64xx/usb-hs-otg.h
new file mode 100644 (file)
index 0000000..4df1081
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_USB_HS_OTG_H_
+#define __ASM_ARCH_USB_HS_OTG_H_
+
+/*
+ * USB2.0 HS OTG
+ */
+#define S5PC100_OTG_BASE       0xED200000
+#define S5PC100_PHY_BASE       0xED300000
+
+#define S5PC110_OTG_BASE       0xEC000000
+#define S5PC110_PHY_BASE       0xEC100000
+
+/* Core Global Registers */
+#define OTG_GOTGCTL            0x000
+#define OTG_GOTGINT            0x004
+#define OTG_GAHBCFG            0x008
+#define OTG_GUSBCFG            0x00C
+#define OTG_GRSTCTL            0x010
+#define OTG_GINTSTS            0x014
+#define OTG_GINTMSK            0x018
+#define OTG_GRXSTSR            0x01C
+#define OTG_GRXSTSP            0x020
+#define OTG_GRXFSIZ            0x024
+#define OTG_GNPTXFSIZ          0x028
+#define OTG_GNPTXSTS           0x02C
+
+#define OTG_HPTXFSIZ           0x100
+#define OTG_DPTXFSIZ1          0x104
+#define OTG_DPTXFSIZ2          0x108
+#define OTG_DPTXFSIZ3          0x10C
+#define OTG_DPTXFSIZ4          0x110
+#define OTG_DPTXFSIZ5          0x114
+#define OTG_DPTXFSIZ6          0x118
+#define OTG_DPTXFSIZ7          0x11C
+#define OTG_DPTXFSIZ8          0x120
+#define OTG_DPTXFSIZ9          0x124
+#define OTG_DPTXFSIZ10         0x128
+#define OTG_DPTXFSIZ11         0x12C
+#define OTG_DPTXFSIZ12         0x130
+#define OTG_DPTXFSIZ13         0x134
+#define OTG_DPTXFSIZ14         0x138
+#define OTG_DPTXFSIZ15         0x13C
+
+/* Host Global Registers */
+#define OTG_HCFG               0x400
+#define OTG_HFIR               0x404
+#define OTG_HFNUM              0x408
+#define OTG_HPTXSTS            0x410
+#define OTG_HAINT              0x414
+#define OTG_HAINTMSK           0x418
+
+/* Host Port Control & Status Registers */
+#define OTG_HPRT               0x440
+
+/* Host Channel-Specific Registers */
+#define OTG_HCCHAR0            0x500
+#define OTG_HCSPLT0            0x504
+#define OTG_HCINT0             0x508
+#define OTG_HCINTMSK0          0x50C
+#define OTG_HCTSIZ0            0x510
+#define OTG_HCDMA0             0x514
+
+/* Device Global Registers */
+#define OTG_DCFG               0x800
+#define OTG_DCTL               0x804
+#define OTG_DSTS               0x808
+#define OTG_DIEPMSK            0x810
+#define OTG_DOEPMSK            0x814
+#define OTG_DAINT              0x818
+#define OTG_DAINTMSK           0x81C
+#define OTG_DTKNQR1            0x820
+#define OTG_DTKNQR2            0x824
+#define OTG_DVBUSDIS           0x828
+#define OTG_DVBUSPULSE         0x82C
+#define OTG_DTKNQR3            0x830
+#define OTG_DTKNQR4            0x834
+
+/* Device Logical IN Endpoint-Specific Registers */
+#define OTG_DIEPCTL0           0x900
+#define OTG_DIEPINT0           0x908
+#define OTG_DIEPTSIZ0          0x910
+#define OTG_DIEPDMA0           0x914
+
+/* Device Logical OUT Endpoint-Specific Registers */
+#define OTG_DOEPCTL0           0xB00
+#define OTG_DOEPINT0           0xB08
+#define OTG_DOEPTSIZ0          0xB10
+#define OTG_DOEPDMA0           0xB14
+
+/* Power & clock gating registers */
+#define OTG_PCGCCTRL           0xE00
+
+/* Endpoint FIFO address */
+#define OTG_EP0_FIFO           0x1000
+
+/* OTG PHY CORE REGISTERS */
+#define OTG_PHYPWR             0x0
+#define OTG_PHYCTRL            0x4
+#define OTG_RSTCON             0x8
+
+#endif
diff --git a/include/configs/smdk6442.h b/include/configs/smdk6442.h
new file mode 100644 (file)
index 0000000..4759983
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * Configuation settings for the SAMSUNG 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
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_SAMSUNG         1       /* in a SAMSUNG core */
+#define CONFIG_S5P64XX         1       /* which is in a S5P64XX Family */
+#define CONFIG_S5P6442         1       /* which is in a S5P6442 */
+
+#include <asm/arch/cpu.h>              /* get chip and board defs */
+
+#define CONFIG_ARCH_CPU_INIT
+
+#define CONFIG_SYS_SDRAM_BASE  0x20000000
+
+/* input clock of PLL: Universal has 12MHz/24MHz input clock at S5PC100/C110 */
+#define CONFIG_SYS_CLK_FREQ_6442       12000000
+
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_INITRD_TAG
+//#define CONFIG_REVISION_TAG
+
+/*
+ * Architecture magic and machine type
+ */
+#define CONFIG_DISPLAY_CPUINFO
+
+#undef CONFIG_SKIP_RELOCATE_UBOOT
+
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_SYS_MALLOC_LEN          (CONFIG_ENV_SIZE + 1024 * 1024)
+#define CONFIG_SYS_GBL_DATA_SIZE       128     /* size in bytes for initial data */
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_SERIAL_MULTI    1
+#define CONFIG_SERIAL2          1      /* we use SERIAL 2 on S5PC100 */
+
+#if 0
+/* MMC */
+#define CONFIG_GENERIC_MMC     1
+#define CONFIG_MMC             1
+#define CONFIG_S5PC1XX_MMC     1
+#define CONFIG_MMC_INDEX       0
+#endif
+
+#define CONFIG_SYS_HUSH_PARSER         /* use "hush" command parser    */
+#ifdef CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2     "> "
+#endif
+
+#define CONFIG_CMDLINE_EDITING
+
+#define CONFIG_BAUDRATE                115200
+
+/* It should define before config_cmd_default.h */
+#define CONFIG_SYS_NO_FLASH            1
+/***********************************************************
+ * Command definition
+ ***********************************************************/
+#include <config_cmd_default.h>
+
+#undef CONFIG_CMD_LOADB
+#undef CONFIG_CMD_LOADS
+#undef CONFIG_CMD_BOOTD
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_XIMG
+#undef CONFIG_CMD_NAND
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_NET
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_ONENAND
+#define CONFIG_CMD_MTDPARTS
+#if 0
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_SLEEP
+#define CONFIG_CMD_GPIO
+#define CONFIG_CMD_PMIC
+#define CONFIG_CMD_DEVICE_POWER
+#endif
+
+#define CONFIG_SYS_64BIT_VSPRINTF      1
+
+#define CONFIG_BOOTDELAY       1
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+
+#define CONFIG_NETMASK         255.255.255.0
+#define CONFIG_IPADDR          192.168.129.3
+#define CONFIG_SERVERIP                192.168.129.1
+#define CONFIG_GATEWAYIP       192.168.129.1
+#define CONFIG_ETHADDR         00:0E:99:34:10:00
+
+#define CONFIG_MTD_DEVICE
+#define CONFIG_MTD_PARTITIONS
+
+/* Actual modem binary size is 16MiB. Add 2MiB for bad block handling */
+#define MTDIDS_DEFAULT         "onenand0=samsung-onenand"
+#define MTDPARTS_DEFAULT       "mtdparts=samsung-onenand:256k(bootloader)"\
+                               ",128k(params)"\
+                               ",3m(kernel)"\
+                               ",18m(modem)"\
+                               ",7m(fota)"\
+                               ",9m(log)"\
+                               ",-(UBI)\0"
+
+#define MTDPARTS_DEFAULT_4KB   "mtdparts=samsung-onenand:256k(bootloader)"\
+                               ",256k(params)"\
+                               ",3m(kernel)"\
+                               ",18m(modem)"\
+                               ",7m(fota)"\
+                               ",9m(log)"\
+                               ",-(UBI)\0"
+
+#define NORMAL_MTDPARTS_DEFAULT MTDPARTS_DEFAULT
+
+#define CONFIG_BOOTCOMMAND     "run ubifsboot"
+
+#define CONFIG_RAMDISK_BOOT    "root=/dev/ram0 rw rootfstype=ext2" \
+               " console=ttySAC2,115200n8" \
+               " ${meminfo}"
+
+#define CONFIG_COMMON_BOOT     "console=ttySAC2,115200n8" \
+               " ${meminfo}" \
+               " ${mtdparts}"
+
+#define CONFIG_BOOTARGS        "root=/dev/mtdblock7 ubi.mtd=6" \
+               " rootfstype=cramfs " CONFIG_COMMON_BOOT
+
+#define CONFIG_UPDATEB "updateb=onenand erase 0x0 0x40000;" \
+                       " onenand write 0x32008000 0x0 0x40000\0"
+
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#define CONFIG_EXTRA_ENV_SETTINGS                                      \
+       CONFIG_UPDATEB \
+       "updatek=onenand erase 0x80000 0x300000;" \
+       " onenand write 0x31008000 0x80000 0x300000\0" \
+       "updateu=onenand erase 0x01560000 0x1eaa0000;" \
+       " onenand write 0x32000000 0x1260000 0x8C0000\0" \
+       "bootk=onenand read 0x30007FC0 0x80000 0x300000;" \
+       " bootm 0x30007FC0\0" \
+       "flashboot=set bootargs root=/dev/mtdblock${bootblock}" \
+        " rootfstype=${rootfstype}" \
+        " ubi.mtd=${ubiblock} ${opts} ${lcdinfo} " CONFIG_COMMON_BOOT "; run bootk\0" \
+       "ubifsboot=set bootargs root=ubi0!rootfs rootfstype=ubifs" \
+        " ubi.mtd=${ubiblock} ${opts} ${lcdinfo} " CONFIG_COMMON_BOOT "; run bootk\0" \
+       "boottrace=setenv opts initcall_debug; run bootcmd\0" \
+       "android=set bootargs root=ubi0!ramdisk ubi.mtd=${ubiblock}" \
+        " rootfstype=ubifs init=/init.sh " CONFIG_COMMON_BOOT "; run bootk\0" \
+       "nfsboot=set bootargs root=/dev/nfs rw ubi.mtd=${ubiblock}" \
+        " nfsroot=${nfsroot},nolock,tcp ip=${ipaddr}:${serverip}:${gatewayip}:" \
+        "${netmask}:generic:usb0:off " CONFIG_COMMON_BOOT "; run bootk\0" \
+       "ramboot=set bootargs " CONFIG_RAMDISK_BOOT \
+        " initrd=0x33000000,8M ramdisk=8192\0" \
+       "mmcboot=set bootargs root=${mmcblk} rootfstype=${rootfstype}" \
+        " ubi.mtd=${ubiblock} ${opts} ${lcdinfo} " CONFIG_COMMON_BOOT "; run bootk\0" \
+       "verify=n\0" \
+       "rootfstype=cramfs\0" \
+       "mtdparts=" MTDPARTS_DEFAULT \
+       "meminfo=mem=80M mem=128M@0x40000000\0" \
+       "nfsroot=/nfsroot/arm\0" \
+       "mmcblk=/dev/mmcblk1p1\0" \
+       "bootblock=7\0" \
+       "ubiblock=6\0" \
+       "ubi=enabled"
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP    /* undef to save memory */
+#define CONFIG_SYS_PROMPT      "6442 # "       /* Monitor Command Prompt */
+#define CONFIG_SYS_CBSIZE      256     /* Console I/O Buffer Size */
+#define CONFIG_SYS_PBSIZE      384     /* Print Buffer Size */
+#define CONFIG_SYS_MAXARGS     16      /* max number of command args */
+#define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE       /* Boot Argument Buffer Size */
+
+#define CONFIG_SYS_MEMTEST_START       CONFIG_SYS_SDRAM_BASE   /* memtest works on           */
+#define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_SDRAM_BASE + 0x5000000)
+
+#define CONFIG_SYS_LOAD_ADDR           (CONFIG_SYS_SDRAM_BASE + 0x4800000)
+
+#define CONFIG_SYS_HZ                  1000
+
+/* valid baudrates */
+#define CONFIG_SYS_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200 }
+
+/* base address for uboot */
+#define CONFIG_SYS_PHY_UBOOT_BASE      (CONFIG_SYS_SDRAM_BASE + 0x04800000)
+
+/*-----------------------------------------------------------------------
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE       (256 << 10)     /* regular stack 256KB */
+
+/*******************************
+ Support Clock Settings(APLL)
+ *******************************
+ ARMCLK                HCLKD0          PCLKD0
+ -------------------------------
+ 667           166                     83
+ 600           150                     75
+ 533           133                     66
+ 500           166                     66
+ 467           117                     59
+ 400           100                     50
+ *******************************/
+
+#define CONFIG_CLK_667_166_83
+/*#define CONFIG_CLK_666_166_66*/
+/*#define CONFIG_CLK_600_150_75*/
+/*#define CONFIG_CLK_533_133_66*/
+/*#define CONFIG_CLK_500_166_66*/
+/*#define CONFIG_CLK_467_117_59*/
+/*#define CONFIG_CLK_400_100_50*/
+
+/* Universal has 2 banks of DRAM, but swap the bank */
+#define CONFIG_NR_DRAM_BANKS   1
+#define PHYS_SDRAM_1           CONFIG_SYS_SDRAM_BASE   /* OneDRAM Bank #0 */
+#define PHYS_SDRAM_1_SIZE      (80 << 20)              /* 80 MB in Bank #0 */
+
+#define CONFIG_SYS_MONITOR_BASE        0x00000000
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+
+#define CONFIG_SYS_MONITOR_LEN         (256 << 10)     /* Reserve 2 sectors */
+
+/* OneNAND IPL uses 8KiB */
+#define CONFIG_ONENAND_START_PAGE      4
+
+#define CONFIG_ENV_IS_IN_ONENAND       1
+#define CONFIG_ENV_SIZE                        (256 << 10)     /* 256 KiB, 0x40000 */
+#define CONFIG_ENV_ADDR                        (256 << 10)     /* 256 KiB, 0x40000 */
+#define CONFIG_ENV_OFFSET              (256 << 10)     /* 256 KiB, 0x40000 */
+
+#define CONFIG_USE_ONENAND_BOARD_INIT
+#define CONFIG_SAMSUNG_ONENAND         1
+#define CONFIG_SYS_ONENAND_BASE                0xB0000000
+
+#define CONFIG_DOS_PARTITION   1
+
+//#define CONFIG_MISC_INIT_R
+
+#if 0
+/* I2C */
+#if 0
+#define CONFIG_DRIVER_S5PC1XX_I2C
+#define CONFIG_HARD_I2C                1
+#define CONFIG_SYS_I2C_SPEED   50000
+#define CONFIG_SYS_I2C_SLAVE   0xFE
+#define CONFIG_SYS_I2C_0       1
+#else
+#include <i2c-gpio.h>
+#define CONFIG_SOFT_I2C                1
+#define CONFIG_SYS_I2C_INIT_BOARD
+#define CONFIG_SYS_I2C_SPEED   50000
+#define CONFIG_I2C_MULTI_BUS
+#define CONFIG_SYS_MAX_I2C_BUS 6
+#endif
+
+/* USB Downloader */
+#define CONFIG_CMD_USBDOWN
+#define CONFIG_SAMSUNG_USB
+#define CONFIG_OTG_CLK_OSCC
+#define CONFIG_SYS_DOWN_ADDR   CONFIG_SYS_SDRAM_BASE
+#define CONFIG_RAMDISK_ADDR    (CONFIG_SYS_SDRAM_BASE + 0x03000000)
+
+/* LCD */
+#if 1          /* For LCD test */
+#define CONFIG_LCD             1
+#define CONFIG_S5PC1XXFB       1
+#endif
+
+#if 0
+#define CONFIG_CMD_EXT2                        1
+#define CONFIG_CMD_ONENAND_EXT2                1
+#endif
+#endif
+
+#endif /* __CONFIG_H */
index f2638ec..eadcc68 100644 (file)
@@ -43,7 +43,7 @@ extern struct serial_device s3c24xx_serial1_device;
 extern struct serial_device s3c24xx_serial2_device;
 #endif
 
-#if defined(CONFIG_S5PC1XX)
+#if defined(CONFIG_S5PC1XX) || defined(CONFIG_S5P64XX)
 extern struct serial_device s5pc1xx_serial0_device;
 extern struct serial_device s5pc1xx_serial1_device;
 extern struct serial_device s5pc1xx_serial2_device;