fi
@echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
+smdk6442_config: unconfig
+ @$(MKCONFIG) $(@:_config=) arm arm1176 smdk6442 samsung s5p64xx
+
#========================================================================
# i386
#========================================================================
--- /dev/null
+#
+# (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
+
+#########################################################################
--- /dev/null
+#
+# Copyright (C) 2010 Samsung Elecgtronics
+# Minkyu Kang <mk7.kang@samsung.com>
+#
+
+TEXT_BASE = 0x24800000
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+}
--- /dev/null
+/*
+ * 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
#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)
#include <common.h>
#include <command.h>
+#ifdef CONFIG_S3C64XX
#include <asm/arch/s3c6400.h>
+#endif
#include <asm/system.h>
static void cache_flush (void);
--- /dev/null
+#
+# (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
+
+#########################################################################
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * (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
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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"
+);
--- /dev/null
+/*
+ * 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
--- /dev/null
+/* 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
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * (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
--- /dev/null
+/*
+ * 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;
+}
#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
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
{
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
}
/*
--- /dev/null
+/*
+ * (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
--- /dev/null
+/*
+ * (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
--- /dev/null
+/*
+ * (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 */
--- /dev/null
+/*
+ * (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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * (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
--- /dev/null
+/*
+ * (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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/* 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 */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * (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
--- /dev/null
+/*
+ * (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
--- /dev/null
+/*
+ * 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 */
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;