U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
October 2009
- 193 participants
- 559 discussions
All arches apparently should reset the watchdog in their udelay loop as
noted on the mailing list recently:
> A comment in flash_status_check() suggests that udelay() is
> expected to reset the watchdog, but I can't find any architecture
> where it does.
If this is missing in other architectures, it should be fixed at the
root cause, i. e. in udelay() or in the respective support routines.
Signed-off-by: Mike Frysinger <vapier(a)gentoo.org>
---
cpu/blackfin/interrupts.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/cpu/blackfin/interrupts.c b/cpu/blackfin/interrupts.c
index bf6fb4b..7ab4cc4 100644
--- a/cpu/blackfin/interrupts.c
+++ b/cpu/blackfin/interrupts.c
@@ -70,6 +70,8 @@ void udelay(unsigned long usec)
cclk = (CONFIG_CCLK_HZ);
while (usec > 1) {
+ WATCHDOG_RESET();
+
/*
* how many clock ticks to delay?
* - request(in useconds) * clock_ticks(Hz) / useconds/second
--
1.6.5.rc2
1
1
Blackfin pieces like commit 0630535e2d062dd73c1ceca5c6125c86d1127a49.
Signed-off-by: Mike Frysinger <vapier(a)gentoo.org>
---
include/asm-blackfin/config.h | 3 +++
include/asm-blackfin/global_data.h | 1 -
lib_blackfin/board.c | 2 --
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/asm-blackfin/config.h b/include/asm-blackfin/config.h
index 25794dd..327843d 100644
--- a/include/asm-blackfin/config.h
+++ b/include/asm-blackfin/config.h
@@ -18,6 +18,9 @@
# define CONFIG_BFIN_SCRATCH_REG retn
#endif
+/* Relocation to SDRAM works on all Blackfin boards */
+#define CONFIG_RELOC_FIXUP_WORKS
+
/* Make sure the structure is properly aligned */
#if ((CONFIG_SYS_GBL_DATA_ADDR & -4) != CONFIG_SYS_GBL_DATA_ADDR)
# error CONFIG_SYS_GBL_DATA_ADDR: must be 4 byte aligned
diff --git a/include/asm-blackfin/global_data.h b/include/asm-blackfin/global_data.h
index 3194b72..b78b04c 100644
--- a/include/asm-blackfin/global_data.h
+++ b/include/asm-blackfin/global_data.h
@@ -44,7 +44,6 @@ typedef struct global_data {
unsigned long baudrate;
unsigned long have_console; /* serial_init() was called */
phys_size_t ram_size; /* RAM size */
- unsigned long reloc_off; /* Relocation Offset */
unsigned long env_addr; /* Address of Environment struct */
unsigned long env_valid; /* Checksum of Environment valid? */
#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c
index 1053f69..322156e 100644
--- a/lib_blackfin/board.c
+++ b/lib_blackfin/board.c
@@ -289,7 +289,6 @@ static void board_net_init_r(bd_t *bd)
void board_init_r(gd_t * id, ulong dest_addr)
{
- extern void malloc_bin_reloc(void);
char *s;
bd_t *bd;
gd = id;
@@ -303,7 +302,6 @@ void board_init_r(gd_t * id, ulong dest_addr)
/* initialize malloc() area */
mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);
- malloc_bin_reloc();
#if !defined(CONFIG_SYS_NO_FLASH)
/* Initialize the flash and protect u-boot by default */
--
1.6.5.rc2
1
0

Re: [U-Boot] [PATCH-ARM 1/4, v2] Clean-up of cpu_arm920t and cpu_arm920t_s3c24x0 code
by Minkyu Kang 09 Oct '09
by Minkyu Kang 09 Oct '09
09 Oct '09
Dear kevin Morfitt
sorry for blank message
2009/9/30 Minkyu Kang <promsoft(a)gmail.com>:
> Dear Kevin Morfitt
>
> 2009/9/26 kevin.morfitt(a)fearnside-systems.co.uk
> <kevin.morfitt(a)fearnside-systems.co.uk>:
>> Changes since v1:
>> - re-formatted patch to remove line wrapping
>>
>> Note that patch 2/4 of this series has not changed.
>>
>> This patch re-formats the code in cpu/arm920t and cpu/arm920t/23c24x0 in
>> preparation for changes to add support for the Embest SBC2440-II Board.
>>
>> The changes are as follows:
>> - re-indent the code using Lindent
>> - make sure register layouts are defined using a C struct
>> - replace the upper-case typedef'ed C struct names with lower case
>> Â non-typedef'ed ones
>> - make sure registers are accessed using the proper accessor functions
>> - run checkpatch.pl and fix any error reports
>>
>> Note that usb_ohci.c still has two lines that exceed 80 characters. This is
>> because the statements on those lines lose readability when wrapped - the Linux
>> coding style guidelines allow for this.
>>
>> It assumes the following patch has been applied first:
>> - [U-Boot][PATCH-ARM] CONFIG_SYS_HZ fix for ARM902T S3C24X0 Boards, 05/09/2009
>>
>> Tested on an Embest SBC2440-II Board with local u-boot patches as I don't have
>> any s3c2400 or s3c2410 boards but need this patch applying before I can submit
>> patches for the SBC2440-II Board. Also, ran MAKEALL for all ARM9 targets and no
>> new warnings or errors were found.
>>
>> Signed-off-by: Kevin Morfitt <kevin.morfitt(a)fearnside-systems.co.uk>
>> ---
>> Â cpu/arm920t/s3c24x0/interrupts.c | Â Â 2 +-
>>  cpu/arm920t/s3c24x0/speed.c    |  42 +-
>>  cpu/arm920t/s3c24x0/timer.c    |  74 ++-
>>  cpu/arm920t/s3c24x0/usb.c     |  30 +-
>>  cpu/arm920t/s3c24x0/usb_ohci.c  | 1268 ++++++++++++++++++++------------------
>>  cpu/arm920t/s3c24x0/usb_ohci.h  |  187 +++---
>> Â cpu/arm920t/start.S Â Â Â Â Â Â Â | Â 63 +-
>> Â 7 files changed, 873 insertions(+), 793 deletions(-)
>>
I didn't see all of your patch.
But there are remained more works for cleaning
please use lower case name at C structure's members and functions
Thanks
Minkyu Kang
--
from. prom.
www.promsoft.net
3
4

[U-Boot] [PATCH-ARM] CONFIG_SYS_HZ fix for ARM902T S3C24X0 Boards
by kevin.morfittï¼ fearnside-systems.co.uk 09 Oct '09
by kevin.morfittï¼ fearnside-systems.co.uk 09 Oct '09
09 Oct '09
This sets CONFIG_SYS_HZ to 1000 for all boards that use the s3c2400 and
s3c2410 cpu's which fixes various problems such as the timeouts in tftp being
too short.
Tested on an Embest SBC2440-II Board with local u-boot patches as I don't
have any s3c2400 or s3c2410 boards but need this patch applying before I can
submit patches for the SBC2440-II Board. Also, ran MAKEALL for all ARM9 targets
and no new warnings or errors were found.
It was originally submitted on 21/06/2009 but didn't get into the 2009.08
release, and Jean-Pierre made one comment on the original patch (see
http://lists.denx.de/pipermail/u-boot/2009-July/055470.html). I've made two
changes to the original patch:
- it's been re-based to the current release
- I've re-named get_timer_raw() to get_ticks() in response to Jean-Pierre's comment
This affects the sbc2410, smdk2400, smdk2410 and trab boards. I've copied it
directly to the maintainers of all except the sbc2410 which doesn't have an
entry in MAINTAINERS.
Signed-off-by: Kevin Morfitt <kmorfitt(a)aselaptop-1.localdomain>
---
cpu/arm920t/s3c24x0/timer.c | 36 ++++++++++++++++++++----------------
include/configs/sbc2410x.h | 4 +---
include/configs/smdk2400.h | 4 +---
include/configs/smdk2410.h | 4 +---
include/configs/trab.h | 12 +-----------
5 files changed, 24 insertions(+), 36 deletions(-)
diff --git a/cpu/arm920t/s3c24x0/timer.c b/cpu/arm920t/s3c24x0/timer.c
index c8c7cdb..db472bf 100644
--- a/cpu/arm920t/s3c24x0/timer.c
+++ b/cpu/arm920t/s3c24x0/timer.c
@@ -39,6 +39,7 @@
#endif
int timer_load_val = 0;
+static ulong timer_clk;
/* macro to read the 16 bit timer */
static inline ulong READ_TIMER(void)
@@ -66,6 +67,7 @@ int timer_init (void)
* @33.25MHz and 15625 @ 50 MHz
*/
timer_load_val = get_PCLK()/(2 * 16 * 100);
+ timer_clk = get_PCLK() / (2 * 16);
}
/* load value for 10 ms timeout */
lastdec = timers->TCNTB4 = timer_load_val;
@@ -100,13 +102,13 @@ void set_timer (ulong t)
void udelay (unsigned long usec)
{
ulong tmo;
- ulong start = get_timer(0);
+ ulong start = get_ticks();
tmo = usec / 1000;
tmo *= (timer_load_val * 100);
tmo /= 1000;
- while ((ulong)(get_timer_masked () - start) < tmo)
+ while ((ulong) (get_ticks() - start) < tmo)
/*NOP*/;
}
@@ -119,18 +121,9 @@ void reset_timer_masked (void)
ulong get_timer_masked (void)
{
- ulong now = READ_TIMER();
-
- if (lastdec >= now) {
- /* normal mode */
- timestamp += lastdec - now;
- } else {
- /* we have an overflow ... */
- timestamp += lastdec + timer_load_val - now;
- }
- lastdec = now;
+ ulong tmr = get_ticks();
- return timestamp;
+ return tmr / (timer_clk / CONFIG_SYS_HZ);
}
void udelay_masked (unsigned long usec)
@@ -148,10 +141,10 @@ void udelay_masked (unsigned long usec)
tmo /= (1000*1000);
}
- endtime = get_timer_masked () + tmo;
+ endtime = get_ticks() + tmo;
do {
- ulong now = get_timer_masked ();
+ ulong now = get_ticks();
diff = endtime - now;
} while (diff >= 0);
}
@@ -162,7 +155,18 @@ void udelay_masked (unsigned long usec)
*/
unsigned long long get_ticks(void)
{
- return get_timer(0);
+ ulong now = READ_TIMER();
+
+ if (lastdec >= now) {
+ /* normal mode */
+ timestamp += lastdec - now;
+ } else {
+ /* we have an overflow ... */
+ timestamp += lastdec + timer_load_val - now;
+ }
+ lastdec = now;
+
+ return timestamp;
}
/*
diff --git a/include/configs/sbc2410x.h b/include/configs/sbc2410x.h
index f2ea926..e6886cf 100644
--- a/include/configs/sbc2410x.h
+++ b/include/configs/sbc2410x.h
@@ -139,9 +139,7 @@
#define CONFIG_SYS_LOAD_ADDR 0x33000000 /* default load address */
-/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
-/* it to wrap 100 times (total 1562500) to get 1 sec. */
-#define CONFIG_SYS_HZ 1562500
+#define CONFIG_SYS_HZ 1000
/* valid baudrates */
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
diff --git a/include/configs/smdk2400.h b/include/configs/smdk2400.h
index c234177..a1beb65 100644
--- a/include/configs/smdk2400.h
+++ b/include/configs/smdk2400.h
@@ -141,9 +141,7 @@
#define CONFIG_SYS_LOAD_ADDR 0x0cf00000 /* default load address */
-/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
-/* it to wrap 100 times (total 1562500) to get 1 sec. */
-#define CONFIG_SYS_HZ 1562500
+#define CONFIG_SYS_HZ 1000
/* valid baudrates */
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
diff --git a/include/configs/smdk2410.h b/include/configs/smdk2410.h
index d340098..c57751b 100644
--- a/include/configs/smdk2410.h
+++ b/include/configs/smdk2410.h
@@ -124,9 +124,7 @@
#define CONFIG_SYS_LOAD_ADDR 0x33000000 /* default load address */
-/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
-/* it to wrap 100 times (total 1562500) to get 1 sec. */
-#define CONFIG_SYS_HZ 1562500
+#define CONFIG_SYS_HZ 1000
/* valid baudrates */
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
diff --git a/include/configs/trab.h b/include/configs/trab.h
index 43c191b..97f30ce 100644
--- a/include/configs/trab.h
+++ b/include/configs/trab.h
@@ -320,17 +320,7 @@
#define CONFIG_SYS_LOAD_ADDR 0x0CF00000 /* default load address */
-#ifdef CONFIG_TRAB_50MHZ
-/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
-/* it to wrap 100 times (total 1562500) to get 1 sec. */
-/* this should _really_ be calculated !! */
-#define CONFIG_SYS_HZ 1562500
-#else
-/* the PWM TImer 4 uses a counter of 10390 for 10 ms, so we need */
-/* it to wrap 100 times (total 1039000) to get 1 sec. */
-/* this should _really_ be calculated !! */
-#define CONFIG_SYS_HZ 1039000
-#endif
+#define CONFIG_SYS_HZ 1000
/* valid baudrates */
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
--
1.6.0.6
5
7
Add new board SMDKC100 that uses s5pc100 SoC
Signed-off-by: Minkyu Kang <mk7.kang(a)samsung.com>
Signed-off-by: HeungJun, Kim <riverful.kim(a)samsung.com>
---
MAINTAINERS | 4 +
MAKEALL | 1 +
Makefile | 3 +
board/samsung/smdkc100/Makefile | 54 +++++++
board/samsung/smdkc100/config.mk | 16 ++
board/samsung/smdkc100/lowlevel_init.S | 221 ++++++++++++++++++++++++++++
board/samsung/smdkc100/mem_setup.S | 198 +++++++++++++++++++++++++
board/samsung/smdkc100/onenand.c | 78 ++++++++++
board/samsung/smdkc100/smdkc100.c | 51 +++++++
include/configs/smdkc100.h | 247 ++++++++++++++++++++++++++++++++
10 files changed, 873 insertions(+), 0 deletions(-)
create mode 100644 board/samsung/smdkc100/Makefile
create mode 100644 board/samsung/smdkc100/config.mk
create mode 100644 board/samsung/smdkc100/lowlevel_init.S
create mode 100644 board/samsung/smdkc100/mem_setup.S
create mode 100644 board/samsung/smdkc100/onenand.c
create mode 100644 board/samsung/smdkc100/smdkc100.c
create mode 100644 include/configs/smdkc100.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 439c1b8..eddf736 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -725,6 +725,10 @@ Alex Z
lart SA1100
dnp1110 SA1110
+Minkyu Kang <mk7.kang(a)samsung.com>
+
+ SMDKC100 ARM CORTEX-A8 (S5PC100 SoC)
+
-------------------------------------------------------------------------
Unknown / orphaned boards:
diff --git a/MAKEALL b/MAKEALL
index 13f3f5e..0b779dc 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -588,6 +588,7 @@ LIST_ARM_CORTEX_A8=" \
omap3_pandora \
omap3_zoom1 \
omap3_zoom2 \
+ smdkc100 \
"
#########################################################################
diff --git a/Makefile b/Makefile
index df22bff..8f69c17 100644
--- a/Makefile
+++ b/Makefile
@@ -3169,6 +3169,9 @@ omap3_zoom1_config : unconfig
omap3_zoom2_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm_cortexa8 zoom2 logicpd omap3
+smdkc100_config: unconfig
+ @$(MKCONFIG) $(@:_config=) arm arm_cortexa8 smdkc100 samsung s5pc1xx
+
#########################################################################
## XScale Systems
#########################################################################
diff --git a/board/samsung/smdkc100/Makefile b/board/samsung/smdkc100/Makefile
new file mode 100644
index 0000000..7d0b6b0
--- /dev/null
+++ b/board/samsung/smdkc100/Makefile
@@ -0,0 +1,54 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd(a)denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg(a)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 := smdkc100.o onenand.o
+SOBJS := lowlevel_init.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(SOBJS) $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(SOBJS) $(OBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/samsung/smdkc100/config.mk b/board/samsung/smdkc100/config.mk
new file mode 100644
index 0000000..ebab420
--- /dev/null
+++ b/board/samsung/smdkc100/config.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2008 # Samsung Elecgtronics
+# Kyungmin Park <kyungmin.park(a)samsung.com>
+#
+
+# On S5PC100 we use the 128 MiB OneDRAM bank at
+#
+# 0x30000000 to 0x35000000 (80MiB)
+# 0x38000000 to 0x40000000 (128MiB)
+#
+# On S5PC110 we use the 128 MiB OneDRAM bank at
+#
+# 0x30000000 to 0x35000000 (80MiB)
+# 0x40000000 to 0x48000000 (128MiB)
+#
+TEXT_BASE = 0x34800000
diff --git a/board/samsung/smdkc100/lowlevel_init.S b/board/samsung/smdkc100/lowlevel_init.S
new file mode 100644
index 0000000..cd512bd
--- /dev/null
+++ b/board/samsung/smdkc100/lowlevel_init.S
@@ -0,0 +1,221 @@
+/*
+ * Memory Setup stuff - taken from blob memsetup.S
+ *
+ * Copyright (C) 2009 Samsung Electronics
+ * Kyungmin Park <kyungmin.park(a)samsung.com>
+ * Minkyu Kang <mk7.kang(a)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/mem.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/power.h>
+#include <asm/arch/interrupt.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, =S5PC100_GPIO_BASE(0)
+
+ /* Disable Watchdog */
+ ldr r0, =S5PC100_WATCHDOG_BASE @0xEA200000
+ orr r0, r0, #0x0
+ str r5, [r0]
+
+#ifndef CONFIG_ONENAND_IPL
+ /* setting SRAM */
+ ldr r0, =S5PC100_SROMC_BASE
+ ldr r1, =0x9
+ str r1, [r0]
+#endif
+
+ /* S5PC100 has 3 groups of interrupt sources */
+ ldr r0, =S5PC100_VIC0_BASE @0xE4000000
+ ldr r1, =S5PC100_VIC1_BASE @0xE4000000
+ ldr r2, =S5PC100_VIC2_BASE @0xE4000000
+
+ /* Disable all interrupts (VIC0, VIC1 and VIC2) */
+ mvn r3, #0x0
+ str r3, [r0, #VIC_INTENCLEAR_OFFSET]
+ str r3, [r1, #VIC_INTENCLEAR_OFFSET]
+ str r3, [r2, #VIC_INTENCLEAR_OFFSET]
+
+#ifndef CONFIG_ONENAND_IPL
+ /* Set all interrupts as IRQ */
+ str r5, [r0, #VIC_INTSELECT_OFFSET]
+ str r5, [r1, #VIC_INTSELECT_OFFSET]
+ str r5, [r2, #VIC_INTSELECT_OFFSET]
+
+ /* Pending Interrupt Clear */
+ str r5, [r0, #VIC_INTADDRESS_OFFSET]
+ str r5, [r1, #VIC_INTADDRESS_OFFSET]
+ str r5, [r2, #VIC_INTADDRESS_OFFSET]
+#endif
+
+#ifndef CONFIG_ONENAND_IPL
+ /* for UART */
+ bl uart_asm_init
+
+ /* for TZPC */
+ bl tzpc_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, =S5PC100_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, =S5PC100_WAKEUP_STAT
+ ldr r1, [r0]
+ str r1, [r0]
+
+ /* Load return address and jump to kernel */
+ ldr r0, =S5PC100_INFORM0
+
+ /* r1 = physical address of s5pc100_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, =S5PC1XX_CLOCK_BASE @ 0xE0100000
+
+ /* Set Clock divider */
+ ldr r1, =0x00011110
+ str r1, [r8, #0x304]
+ ldr r1, =0x1
+ str r1, [r8, #0x308]
+ ldr r1, =0x00011301
+ str r1, [r8, #0x300]
+
+ /* Set Lock Time */
+ ldr r1, =0xe10 @ Locktime : 0xe10 = 3600
+ str r1, [r8, #0x000] @ APLL_LOCK
+ str r1, [r8, #0x004] @ MPLL_LOCK
+ str r1, [r8, #0x008] @ EPLL_LOCK
+ str r1, [r8, #0x00C] @ HPLL_LOCK
+
+ /* APLL_CON */
+ ldr r1, =0x81bc0400 @ SDIV 0, PDIV 4, MDIV 444 (1332MHz)
+ str r1, [r8, #0x100]
+ /* MPLL_CON */
+ ldr r1, =0x80590201 @ SDIV 1, PDIV 2, MDIV 89 (267MHz)
+ str r1, [r8, #0x104]
+ /* EPLL_CON */
+ ldr r1, =0x80870303 @ SDIV 3, PDIV 3, MDIV 135 (67.5MHz)
+ str r1, [r8, #0x108]
+ /* HPLL_CON */
+ ldr r1, =0x80600603
+ str r1, [r8, #0x10C]
+
+ /* Set Source Clock */
+ ldr r1, =0x1111 @ A, M, E, HPLL Muxing
+ str r1, [r8, #0x200] @ CLK_SRC0
+
+ ldr r1, =0x1000001 @ Uart Clock & CLK48M Muxing
+ str r1, [r8, #0x204] @ CLK_SRC1
+
+ ldr r1, =0x9000 @ ARMCLK/4
+ str r1, [r8, #0x400] @ CLK_OUT
+
+ /* 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, #S5PC100_GPIO_A0_OFFSET] @ GPA0_CON
+ ldr r1, =0x00022222
+ str r1, [r0, #S5PC100_GPIO_A1_OFFSET] @ GPA1_CON
+
+ mov pc, lr
+
+/*
+ * tzpc_asm_init: Initialize TZPC
+ */
+tzpc_asm_init:
+ ldr r0, =0xE3800000
+ mov r1, #0x0
+ str r1, [r0]
+ mov r1, #0xff
+ str r1, [r0, #0x804]
+ str r1, [r0, #0x810]
+
+ ldr r0, =0xE2800000
+ str r1, [r0, #0x804]
+ str r1, [r0, #0x810]
+ str r1, [r0, #0x81C]
+
+ ldr r0, =0xE2900000
+ str r1, [r0, #0x804]
+ str r1, [r0, #0x810]
+
+ mov pc, lr
+#endif
diff --git a/board/samsung/smdkc100/mem_setup.S b/board/samsung/smdkc100/mem_setup.S
new file mode 100644
index 0000000..a3e692f
--- /dev/null
+++ b/board/samsung/smdkc100/mem_setup.S
@@ -0,0 +1,198 @@
+/*
+ * Originates from Samsung's u-boot 1.1.6 port to S5PC1xx
+ *
+ * Copyright (C) 2009 Samsung Electrnoics
+ * Inki Dae <inki.dae(a)samsung.com>
+ * Heungjun Kim <riverful.kim(a)samsung.com>
+ * Minkyu Kang <mk7.kang(a)samsung.com>
+ * Kyungmin Park <kyungmin.park(a)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 <asm/arch/mem.h>
+
+ .globl mem_ctrl_asm_init
+mem_ctrl_asm_init:
+ ldr r6, =S5PC100_DMC_BASE @ 0xE6000000
+
+ /* DLL parameter setting */
+ ldr r1, =0x50101000
+ str r1, [r6, #0x018] @ PHYCONTROL0
+ ldr r1, =0xf4
+ str r1, [r6, #0x01C] @ PHYCONTROL1
+ ldr r1, =0x0
+ str r1, [r6, #0x020] @ PHYCONTROL2
+
+ /* DLL on */
+ ldr r1, =0x50101002
+ str r1, [r6, #0x018] @ PHYCONTROL0
+
+ /* DLL start */
+ ldr r1, =0x50101003
+ str r1, [r6, #0x018] @ PHYCONTROL0
+
+ /* Force value locking for DLL off */
+ str r1, [r6, #0x018] @ PHYCONTROL0
+
+ /* DLL off */
+ ldr r1, =0x50101001
+ str r1, [r6, #0x018] @ PHYCONTROL0
+
+ /* auto refresh off */
+ ldr r1, =0xff001010
+ 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, =0x00212100
+ 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
+
+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
+
+ /*
+ * 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, =0x0000050e
+ str r1, [r6, #0x030] @ TIMINGAREF
+
+ /* 166 MHz */
+ ldr r1, =0x0c233287
+ str r1, [r6, #0x034] @ TIMINGROW
+
+ /* twtr=3 twr=2 trtp=3 cl=3 wl=3 rl=3 */
+ ldr r1, =0x32330303
+ str r1, [r6, #0x038] @ TIMINGDATA
+
+ /* tfaw=4 sxsr=0x14 txp=0x14 tcke=3 tmrd=3 */
+ ldr r1, =0x04141433
+ 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, =0xff002030
+ str r1, [r6, #0x000] @ CONCONTROL
+
+ /* PwrdnConfig */
+ ldr r1, =0x00100002
+ str r1, [r6, #0x028] @ PWRDNCONFIG
+
+ /* BL%LE %LONG */
+ ldr r1, =0xff212100
+ str r1, [r6, #0x004] @ MEMCONTROL
+
+
+ /* 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
+
+1:
+ mov pc, lr
+
+ .ltorg
diff --git a/board/samsung/smdkc100/onenand.c b/board/samsung/smdkc100/onenand.c
new file mode 100644
index 0000000..62bbd8a
--- /dev/null
+++ b/board/samsung/smdkc100/onenand.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008-2009 Samsung Electronics
+ * Kyungmin Park <kyungmin.park(a)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)
+{
+ 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);
+ 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);
+
+ writel(0x3, &onenand->ACC_CLOCK);
+
+ writel(0x3fff, &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);
+}
diff --git a/board/samsung/smdkc100/smdkc100.c b/board/samsung/smdkc100/smdkc100.c
new file mode 100644
index 0000000..15a1a27
--- /dev/null
+++ b/board/samsung/smdkc100/smdkc100.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008-2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang(a)samsung.com>
+ * Kyungmin Park <kyungmin.park(a)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:\tSMDKC100\n");
+ return 0;
+}
+#endif
diff --git a/include/configs/smdkc100.h b/include/configs/smdkc100.h
new file mode 100644
index 0000000..251ca40
--- /dev/null
+++ b/include/configs/smdkc100.h
@@ -0,0 +1,247 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang(a)samsung.com>
+ * HeungJun Kim <riverful.kim(a)samsung.com>
+ * Inki Dae <inki.dae(a)samsung.com>
+ *
+ * Configuation settings for the SAMSUNG SMDKC100 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
+#include <asm/sizes.h>
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_ARMCORTEXA8 1 /* This is an ARM V7 CPU core */
+#define CONFIG_SAMSUNG 1 /* in a SAMSUNG core */
+#define CONFIG_S5PC1XX 1 /* which is in a S5PC1XX Family */
+#define CONFIG_S5PC100 1 /* which is in a S5PC100 */
+#define CONFIG_SMDKC100 1 /* working with SMDKC100 */
+
+#include <asm/arch/cpu.h> /* get chip and board defs */
+
+#define CONFIG_ARCH_CPU_INIT
+
+/*
+ * Architecture magic and machine type
+ */
+#define MACH_TYPE_SMDKC100 1826
+
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+
+#undef CONFIG_SKIP_RELOCATE_UBOOT
+
+#define CONFIG_L2_OFF
+
+/* input clock of PLL: SMDKC100 has 12MHz input clock */
+#define CONFIG_SYS_CLK_FREQ 12000000
+
+/* DRAM Base */
+#define CONFIG_SYS_SDRAM_BASE 0x30000000
+
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_INITRD_TAG
+#define CONFIG_CMDLINE_EDITING
+
+/*
+ * Size of malloc() pool
+ * 1MB = 0x100000, 0x100000 = 1024 * 1024
+ */
+#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_1M)
+#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes for */
+ /* initial data */
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_SERIAL0 1 /* use SERIAL 0 on SMDKC100 */
+#define CONFIG_SERIAL_MULTI 1
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_BAUDRATE 115200
+
+/***********************************************************
+ * Command definition
+ ***********************************************************/
+#include <config_cmd_default.h>
+
+#undef CONFIG_CMD_NAND
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_NET
+
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_ONENAND
+#define CONFIG_CMD_ELF
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_MTDPARTS
+
+#define CONFIG_BOOTDELAY 3
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+
+#define CONFIG_MTD_DEVICE
+#define CONFIG_MTD_PARTITIONS
+
+#define MTDIDS_DEFAULT "onenand0=s3c-onenand"
+#define MTDPARTS_DEFAULT "mtdparts=s3c-onenand:256k(bootloader)"\
+ ",128k@0x40000(params)"\
+ ",3m@0x60000(kernel)"\
+ ",16m@0x360000(test)"\
+ ",-(UBI)"
+
+#define NORMAL_MTDPARTS_DEFAULT MTDPARTS_DEFAULT
+
+#define CONFIG_BOOTCOMMAND "run ubifsboot"
+
+#define CONFIG_RAMDISK_BOOT "root=/dev/ram0 rw rootfstype=ext2" \
+ " console=ttySAC0,115200n8" \
+ " mem=128M"
+
+#define CONFIG_COMMON_BOOT "console=ttySAC0,115200n8" \
+ " mem=128M " \
+ " " MTDPARTS_DEFAULT
+
+#define CONFIG_BOOTARGS "root=/dev/mtdblock5 ubi.mtd=4" \
+ " 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_EXTRA_ENV_SETTINGS \
+ CONFIG_UPDATEB \
+ "updatek=" \
+ "onenand erase 0x60000 0x300000;" \
+ "onenand write 0x31008000 0x60000 0x300000\0" \
+ "updateu=" \
+ "onenand erase block 147-4095;" \
+ "onenand write 0x32000000 0x1260000 0x8C0000\0" \
+ "bootk=" \
+ "onenand read 0x30007FC0 0x60000 0x300000;" \
+ "bootm 0x30007FC0\0" \
+ "flashboot=" \
+ "set bootargs root=/dev/mtdblock${bootblock} " \
+ "rootfstype=${rootfstype} " \
+ "ubi.mtd=${ubiblock} ${opts} " CONFIG_COMMON_BOOT ";" \
+ "run bootk\0" \
+ "ubifsboot=" \
+ "set bootargs root=ubi0!rootfs rootfstype=ubifs " \
+ " ubi.mtd=${ubiblock} ${opts} " 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 ubi.mtd=${ubiblock} " \
+ "nfsroot=${nfsroot},nolock " \
+ "ip=${ipaddr}:${serverip}:${gatewayip}:" \
+ "${netmask}:nowplus:usb0:off " CONFIG_COMMON_BOOT "; " \
+ "run bootk\0" \
+ "ramboot=" \
+ "set bootargs " CONFIG_RAMDISK_BOOT \
+ " initrd=0x33000000,8M ramdisk=8192\0" \
+ "rootfstype=cramfs\0" \
+ "mtdparts=" MTDPARTS_DEFAULT "\0" \
+ "meminfo=mem=128M\0" \
+ "nfsroot=/nfsroot/arm\0" \
+ "bootblock=5\0" \
+ "ubiblock=4\0" \
+ "ubi=enabled"
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP /* undef to save memory */
+#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+#define CONFIG_SYS_PROMPT "SMDKC100 # "
+#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 */
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+/* memtest works on */
+#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE
+#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5e00000)
+#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE
+
+#define CONFIG_SYS_HZ 1000
+
+/* valid baudrates */
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+/*-----------------------------------------------------------------------
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE SZ_256K /* regular stack */
+
+/* SMDKC100 has 1 banks of DRAM, we use only one in U-Boot */
+#define CONFIG_NR_DRAM_BANKS 1
+#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE /* SDRAM Bank #1 */
+#define PHYS_SDRAM_1_SIZE SZ_128M /* 0x8000000, 128 MB Bank #1 */
+
+#define CONFIG_SYS_MONITOR_BASE 0x00000000
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+#define CONFIG_SYS_NO_FLASH 1
+
+#define CONFIG_SYS_MONITOR_LEN SZ_256K /* Reserve 2 sectors */
+
+#define CONFIG_IDENT_STRING " for SMDKC100"
+
+#if !defined(CONFIG_NAND_SPL) && (TEXT_BASE >= 0xc0000000)
+#define CONFIG_ENABLE_MMU
+#endif
+
+#ifdef CONFIG_ENABLE_MMU
+#define CONFIG_SYS_MAPPED_RAM_BASE 0xc0000000
+#else
+#define CONFIG_SYS_MAPPED_RAM_BASE CONFIG_SYS_SDRAM_BASE
+#endif
+
+/*-----------------------------------------------------------------------
+ * Boot configuration (define only one of next 3)
+ */
+#define CONFIG_ENV_IS_IN_ONENAND 1
+#define CONFIG_ENV_SIZE SZ_128K /* 128KB, 0x20000 */
+#define CONFIG_ENV_ADDR SZ_256K /* 256KB, 0x40000 */
+#define CONFIG_ENV_OFFSET SZ_256K /* 256KB, 0x40000 */
+
+#define CONFIG_USE_ONENAND_BOARD_INIT
+#define CONFIG_SYS_ONENAND_BASE 0xE7100000
+
+#define CONFIG_DOS_PARTITION 1
+
+#endif /* __CONFIG_H */
--
1.5.4.3
6
14
This patch includes the serial driver for s5pc1xx
Signed-off-by: Minkyu Kang <mk7.kang(a)samsung.com>
---
common/serial.c | 18 +++
drivers/serial/Makefile | 1 +
drivers/serial/serial_s5pc1xx.c | 308 +++++++++++++++++++++++++++++++++++++++
include/serial.h | 7 +
4 files changed, 334 insertions(+), 0 deletions(-)
create mode 100644 drivers/serial/serial_s5pc1xx.c
diff --git a/common/serial.c b/common/serial.c
index 41a24c2..e5ce9fd 100644
--- a/common/serial.c
+++ b/common/serial.c
@@ -69,6 +69,18 @@ struct serial_device *__default_serial_console (void)
#else
#error "CONFIG_SERIAL? missing."
#endif
+#elif defined(CONFIG_S5PC1XX)
+#if defined(CONFIG_SERIAL0)
+ return &s5pc1xx_serial0_device;
+#elif defined(CONFIG_SERIAL1)
+ return &s5pc1xx_serial1_device;
+#elif defined(CONFIG_SERIAL2)
+ return &s5pc1xx_serial2_device;
+#elif defined(CONFIG_SERIAL3)
+ return &s5pc1xx_serial3_device;
+#else
+#error "CONFIG_SERIAL? missing."
+#endif
#elif defined(CONFIG_OMAP3_ZOOM2)
return ZOOM2_DEFAULT_SERIAL_DEVICE;
#else
@@ -139,6 +151,12 @@ void serial_initialize (void)
serial_register(&s3c24xx_serial1_device);
serial_register(&s3c24xx_serial2_device);
#endif
+#if defined(CONFIG_S5PC1XX)
+ serial_register(&s5pc1xx_serial0_device);
+ serial_register(&s5pc1xx_serial1_device);
+ serial_register(&s5pc1xx_serial2_device);
+ serial_register(&s5pc1xx_serial3_device);
+#endif
serial_assign (default_serial_console ()->name);
}
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 64882a2..3c77a7c 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -33,6 +33,7 @@ COBJS-$(CONFIG_NS9750_UART) += ns9750_serial.o
COBJS-$(CONFIG_SYS_NS16550) += ns16550.o
COBJS-$(CONFIG_DRIVER_S3C4510_UART) += s3c4510b_uart.o
COBJS-$(CONFIG_S3C64XX) += s3c64xx.o
+COBJS-$(CONFIG_S5PC1XX) += serial_s5pc1xx.o
COBJS-$(CONFIG_SYS_NS16550_SERIAL) += serial.o
COBJS-$(CONFIG_CLPS7111_SERIAL) += serial_clps7111.o
COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o
diff --git a/drivers/serial/serial_s5pc1xx.c b/drivers/serial/serial_s5pc1xx.c
new file mode 100644
index 0000000..f637f3d
--- /dev/null
+++ b/drivers/serial/serial_s5pc1xx.c
@@ -0,0 +1,308 @@
+/*
+ * (C) Copyright 2009 SAMSUNG Electronics
+ * Minkyu Kang <mk7.kang(a)samsung.com>
+ * Heungjun Kim <riverful.kim(a)samsung.com>
+ *
+ * based on drivers/serial/s3c64xx.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
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/uart.h>
+#include <asm/arch/clk.h>
+
+#if defined(CONFIG_SERIAL_MULTI)
+#include <serial.h>
+
+/* Multi serial device functions */
+#define DECLARE_S5P_SERIAL_FUNCTIONS(port) \
+ int s5p_serial##port##_init(void) { \
+ return serial_init_dev(port); } \
+ void s5p_serial##port##_setbrg(void) { \
+ serial_setbrg_dev(port); } \
+ int s5p_serial##port##_getc(void) { \
+ return serial_getc_dev(port); } \
+ int s5p_serial##port##_tstc(void) { \
+ return serial_tstc_dev(port); } \
+ void s5p_serial##port##_putc(const char c) { \
+ serial_putc_dev(port, c); } \
+ void s5p_serial##port##_puts(const char *s) { \
+ serial_puts_dev(port, s); }
+
+#define INIT_S5P_SERIAL_STRUCTURE(port, name, bus) { \
+ name, \
+ bus, \
+ s5p_serial##port##_init, \
+ s5p_serial##port##_setbrg, \
+ s5p_serial##port##_getc, \
+ s5p_serial##port##_tstc, \
+ s5p_serial##port##_putc, \
+ s5p_serial##port##_puts, }
+#else
+
+#ifdef CONFIG_SERIAL0
+#define UART_NR S5PC1XX_UART0
+#elif defined(CONFIG_SERIAL1)
+#define UART_NR S5PC1XX_UART1
+#elif defined(CONFIG_SERIAL2)
+#define UART_NR S5PC1XX_UART2
+#elif defined(CONFIG_SERIAL3)
+#define UART_NR S5PC1XX_UART3
+#else
+#error "Bad: you didn't configure serial ..."
+#endif
+
+#endif /* CONFIG_SERIAL_MULTI */
+
+static inline struct s5pc1xx_uart *s5pc1xx_get_base_uart(int dev_index)
+{
+ u32 offset = dev_index * 0x400;
+
+ if (cpu_is_s5pc100())
+ return (struct s5pc1xx_uart *)(S5PC100_PA_UART + offset);
+ else
+ return (struct s5pc1xx_uart *)(S5PC110_PA_UART + offset);
+}
+
+/*
+ * The coefficient, used to calculate the baudrate on S5PC1XX UARTs is
+ * calculated as
+ * C = UBRDIV * 16 + number_of_set_bits_in_UDIVSLOT
+ * however, section 31.6.11 of the datasheet doesn't recomment using 1 for 1,
+ * 3 for 2, ... (2^n - 1) for n, instead, they suggest using these constants:
+ */
+static const int udivslot[] = {
+ 0,
+ 0x0080,
+ 0x0808,
+ 0x0888,
+ 0x2222,
+ 0x4924,
+ 0x4a52,
+ 0x54aa,
+ 0x5555,
+ 0xd555,
+ 0xd5d5,
+ 0xddd5,
+ 0xdddd,
+ 0xdfdd,
+ 0xdfdf,
+ 0xffdf,
+};
+
+void _serial_setbrg(const int dev_index)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ struct s5pc1xx_uart *const uart = s5pc1xx_get_base_uart(dev_index);
+ u32 pclk = get_pclk();
+ u32 baudrate = gd->baudrate;
+ u32 val;
+
+ val = pclk / baudrate;
+
+ writel(val / 16 - 1, &uart->UBRDIV);
+ writel(udivslot[val % 16], &uart->UDIVSLOT);
+}
+
+#if defined(CONFIG_SERIAL_MULTI)
+static inline void
+serial_setbrg_dev(unsigned int dev_index)
+{
+ _serial_setbrg(dev_index);
+}
+#else
+void serial_setbrg(void)
+{
+ _serial_setbrg(UART_NR);
+}
+#endif
+
+/*
+ * Initialise the serial port with the given baudrate. The settings
+ * are always 8 data bits, no parity, 1 stop bit, no start bits.
+ */
+int serial_init_dev(const int dev_index)
+{
+ struct s5pc1xx_uart *const uart = s5pc1xx_get_base_uart(dev_index);
+
+ /* reset and enable FIFOs, set triggers to the maximum */
+ writel(0, &uart->UFCON);
+ writel(0, &uart->UMCON);
+ /* 8N1 */
+ writel(0x3, &uart->ULCON);
+ /* No interrupts, no DMA, pure polling */
+ writel(0x245, &uart->UCON);
+
+ _serial_setbrg(dev_index);
+
+ return 0;
+}
+
+#if !defined(CONFIG_SERIAL_MULTI)
+int serial_init(void)
+{
+ return serial_init_dev(UART_NR);
+}
+#endif
+
+/*
+ * Read a single byte from the serial port. Returns 1 on success, 0
+ * otherwise. When the function is succesfull, the character read is
+ * written into its argument c.
+ */
+int _serial_getc(const int dev_index)
+{
+ struct s5pc1xx_uart *const uart = s5pc1xx_get_base_uart(dev_index);
+
+ /* wait for character to arrive */
+ while (!(readl(&uart->UTRSTAT) & 0x1))
+ ;
+
+ return (int)(readl(&uart->URXH) & 0xff);
+}
+
+#if defined(CONFIG_SERIAL_MULTI)
+static inline int serial_getc_dev(unsigned int dev_index)
+{
+ return _serial_getc(dev_index);
+}
+#else
+int serial_getc(void)
+{
+ return _serial_getc(UART_NR);
+}
+#endif
+
+#ifdef CONFIG_MODEM_SUPPORT
+static int be_quiet;
+void disable_putc(void)
+{
+ be_quiet = 1;
+}
+
+void enable_putc(void)
+{
+ be_quiet = 0;
+}
+#endif
+
+/*
+ * Output a single byte to the serial port.
+ */
+void _serial_putc(const char c, const int dev_index)
+{
+ struct s5pc1xx_uart *const uart = s5pc1xx_get_base_uart(dev_index);
+
+#ifdef CONFIG_MODEM_SUPPORT
+ if (be_quiet)
+ return;
+#endif
+
+ /* wait for room in the tx FIFO */
+ while (!(readl(&uart->UTRSTAT) & 0x2))
+ ;
+
+ writel(c, &uart->UTXH);
+
+ /* If \n, also do \r */
+ if (c == '\n')
+ serial_putc('\r');
+}
+
+#if defined(CONFIG_SERIAL_MULTI)
+static inline void serial_putc_dev(unsigned int dev_index, const char c)
+{
+ _serial_putc(c, dev_index);
+}
+#else
+void serial_putc(const char c)
+{
+ _serial_putc(c, UART_NR);
+}
+#endif
+
+/*
+ * Test whether a character is in the RX buffer
+ */
+int _serial_tstc(const int dev_index)
+{
+ struct s5pc1xx_uart *const uart = s5pc1xx_get_base_uart(dev_index);
+
+ return (int)(readl(&uart->UTRSTAT) & 0x1);
+}
+
+#if defined(CONFIG_SERIAL_MULTI)
+static inline int serial_tstc_dev(unsigned int dev_index)
+{
+ return _serial_tstc(dev_index);
+}
+#else
+int serial_tstc(void)
+{
+ return _serial_tstc(UART_NR);
+}
+#endif
+
+void _serial_puts(const char *s, const int dev_index)
+{
+ while (*s)
+ _serial_putc(*s++, dev_index);
+}
+
+#if defined(CONFIG_SERIAL_MULTI)
+static inline void serial_puts_dev(int dev_index, const char *s)
+{
+ _serial_puts(s, dev_index);
+}
+#else
+void serial_puts(const char *s)
+{
+ _serial_puts(s, UART_NR);
+}
+#endif
+
+#ifdef CONFIG_HWFLOW
+static int hwflow; /* turned off by default */
+int hwflow_onoff(int on)
+{
+ switch (on) {
+ case 1:
+ hwflow = 1; /* turn on */
+ break;
+ case -1:
+ hwflow = 0; /* turn off */
+ break;
+ }
+ return hwflow;
+}
+#endif
+
+#if defined(CONFIG_SERIAL_MULTI)
+DECLARE_S5P_SERIAL_FUNCTIONS(0);
+struct serial_device s5pc1xx_serial0_device =
+ INIT_S5P_SERIAL_STRUCTURE(0, "s5pser0", "S5PUART0");
+DECLARE_S5P_SERIAL_FUNCTIONS(1);
+struct serial_device s5pc1xx_serial1_device =
+ INIT_S5P_SERIAL_STRUCTURE(1, "s5pser1", "S5PUART1");
+DECLARE_S5P_SERIAL_FUNCTIONS(2);
+struct serial_device s5pc1xx_serial2_device =
+ INIT_S5P_SERIAL_STRUCTURE(2, "s5pser2", "S5PUART2");
+DECLARE_S5P_SERIAL_FUNCTIONS(3);
+struct serial_device s5pc1xx_serial3_device =
+ INIT_S5P_SERIAL_STRUCTURE(3, "s5pser3", "S5PUART3");
+#endif /* CONFIG_SERIAL_MULTI */
diff --git a/include/serial.h b/include/serial.h
index 821b583..bbda3f0 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -43,6 +43,13 @@ extern struct serial_device s3c24xx_serial1_device;
extern struct serial_device s3c24xx_serial2_device;
#endif
+#if defined(CONFIG_S5PC1XX)
+extern struct serial_device s5pc1xx_serial0_device;
+extern struct serial_device s5pc1xx_serial1_device;
+extern struct serial_device s5pc1xx_serial2_device;
+extern struct serial_device s5pc1xx_serial3_device;
+#endif
+
#if defined(CONFIG_OMAP3_ZOOM2)
extern struct serial_device zoom2_serial_device0;
extern struct serial_device zoom2_serial_device1;
--
1.5.4.3
4
11
This patch includes the onenand driver for s5pc100
Signed-off-by: Minkyu Kang <mk7.kang(a)samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park(a)samsung.com>
---
drivers/mtd/onenand/Makefile | 2 +
drivers/mtd/onenand/samsung.c | 626 +++++++++++++++++++++++++++++++++++
include/linux/mtd/onenand.h | 1 +
include/linux/mtd/onenand_regs.h | 4 +
include/linux/mtd/samsung_onenand.h | 132 ++++++++
5 files changed, 765 insertions(+), 0 deletions(-)
create mode 100644 drivers/mtd/onenand/samsung.c
create mode 100644 include/linux/mtd/samsung_onenand.h
diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
index 1d35a57..9317341 100644
--- a/drivers/mtd/onenand/Makefile
+++ b/drivers/mtd/onenand/Makefile
@@ -26,6 +26,8 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libonenand.a
COBJS-$(CONFIG_CMD_ONENAND) := onenand_uboot.o onenand_base.o onenand_bbt.o
+COBJS-$(CONFIG_S3C64XX) += samsung.o
+COBJS-$(CONFIG_S5PC1XX) += samsung.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c
new file mode 100644
index 0000000..03dfff8
--- /dev/null
+++ b/drivers/mtd/onenand/samsung.c
@@ -0,0 +1,626 @@
+/*
+ * S3C64XX/S5PC100 OneNAND driver at U-Boot
+ *
+ * Copyright (C) 2008-2009 Samsung Electronics
+ * Kyungmin Park <kyungmin.park(a)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.
+ *
+ * Implementation:
+ * Emulate the pseudo BufferRAM
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <linux/mtd/compat.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+#include <linux/mtd/samsung_onenand.h>
+
+#include <asm/io.h>
+#include <asm/errno.h>
+
+#ifdef ONENAND_DEBUG
+#define DPRINTK(format, args...) \
+do { \
+ printf("%s[%d]: " format "\n", __func__, __LINE__, ##args); \
+} while (0)
+#else
+#define DPRINTK(...) do { } while (0)
+#endif
+
+#define ONENAND_ERASE_STATUS 0x00
+#define ONENAND_MULTI_ERASE_SET 0x01
+#define ONENAND_ERASE_START 0x03
+#define ONENAND_UNLOCK_START 0x08
+#define ONENAND_UNLOCK_END 0x09
+#define ONENAND_LOCK_START 0x0A
+#define ONENAND_LOCK_END 0x0B
+#define ONENAND_LOCK_TIGHT_START 0x0C
+#define ONENAND_LOCK_TIGHT_END 0x0D
+#define ONENAND_UNLOCK_ALL 0x0E
+#define ONENAND_OTP_ACCESS 0x12
+#define ONENAND_SPARE_ACCESS_ONLY 0x13
+#define ONENAND_MAIN_ACCESS_ONLY 0x14
+#define ONENAND_ERASE_VERIFY 0x15
+#define ONENAND_MAIN_SPARE_ACCESS 0x16
+#define ONENAND_PIPELINE_READ 0x4000
+
+#if defined(CONFIG_S3C64XX)
+#define MAP_00 (0x0 << 24)
+#define MAP_01 (0x1 << 24)
+#define MAP_10 (0x2 << 24)
+#define MAP_11 (0x3 << 24)
+
+#elif defined(CONFIG_S5PC1XX)
+#define MAP_00 (0x0 << 26)
+#define MAP_01 (0x1 << 26)
+#define MAP_10 (0x2 << 26)
+#define MAP_11 (0x3 << 26)
+
+#endif
+
+/* The 'addr' is byte address. It makes a 16-bit word */
+#define CMD_MAP_00(addr) (MAP_00 | ((addr) << 1))
+#define CMD_MAP_01(mem_addr) (MAP_01 | (mem_addr))
+#define CMD_MAP_10(mem_addr) (MAP_10 | (mem_addr))
+#define CMD_MAP_11(addr) (MAP_11 | ((addr) << 2))
+
+struct s3c_onenand {
+ struct mtd_info *mtd;
+
+ void __iomem *base;
+ void __iomem *ahb_addr;
+
+ int bootram_command;
+
+ void __iomem *page_buf;
+ void __iomem *oob_buf;
+
+ unsigned int (*mem_addr)(int fba, int fpa, int fsa);
+
+ struct samsung_onenand *reg;
+};
+
+static struct s3c_onenand *onenand;
+
+static int s3c_read_cmd(unsigned int cmd)
+{
+ return readl(onenand->ahb_addr + cmd);
+}
+
+static void s3c_write_cmd(int value, unsigned int cmd)
+{
+ writel(value, onenand->ahb_addr + cmd);
+}
+
+/*
+ * 1Gb: FBA[21:12] FPA[11:6] FSA[5:4]
+ * 2Gb: FBA[22:12] FPA[11:6] FSA[5:4]
+ * 4Gb: FBA[23:12] FPA[11:6] FSA[5:4]
+ */
+static unsigned int s3c64xx_mem_addr(int fba, int fpa, int fsa)
+{
+ return (fba << 12) | (fpa << 6) | (fsa << 4);
+}
+
+/*
+ * 1Gb: FBA[22:13] FPA[12:7] FSA[6:5]
+ * 2Gb: FBA[23:13] FPA[12:7] FSA[6:5]
+ * 4Gb: FBA[24:13] FPA[12:7] FSA[6:5]
+ */
+static unsigned int s5pc100_mem_addr(int fba, int fpa, int fsa)
+{
+ return (fba << 13) | (fpa << 7) | (fsa << 5);
+}
+
+static void s3c_onenand_reset(void)
+{
+ unsigned long timeout = 0x10000;
+ int stat;
+
+ writel(ONENAND_MEM_RESET_COLD, &onenand->reg->MEM_RESET);
+ while (timeout--) {
+ stat = readl(&onenand->reg->INT_ERR_STAT);
+ if (stat & RST_CMP)
+ break;
+ }
+ stat = readl(&onenand->reg->INT_ERR_STAT);
+ writel(stat, &onenand->reg->INT_ERR_ACK);
+
+ /* Clear interrupt */
+ writel(0x0, &onenand->reg->INT_ERR_ACK);
+ /* Clear the ECC status */
+ writel(0x0, &onenand->reg->ECC_ERR_STAT);
+}
+
+static unsigned short s3c_onenand_readw(void __iomem *addr)
+{
+ struct onenand_chip *this = onenand->mtd->priv;
+ int reg = addr - this->base;
+ int word_addr = reg >> 1;
+ int value;
+
+ /* It's used for probing time */
+ switch (reg) {
+ case ONENAND_REG_MANUFACTURER_ID:
+ return readl(&onenand->reg->MANUFACT_ID);
+ case ONENAND_REG_DEVICE_ID:
+ return readl(&onenand->reg->DEVICE_ID);
+ case ONENAND_REG_VERSION_ID:
+ return readl(&onenand->reg->FLASH_VER_ID);
+ case ONENAND_REG_DATA_BUFFER_SIZE:
+ return readl(&onenand->reg->DATA_BUF_SIZE);
+ case ONENAND_REG_TECHNOLOGY:
+ return readl(&onenand->reg->TECH);
+ case ONENAND_REG_SYS_CFG1:
+ return readl(&onenand->reg->MEM_CFG);
+
+ /* Used at unlock all status */
+ case ONENAND_REG_CTRL_STATUS:
+ return 0;
+
+ case ONENAND_REG_WP_STATUS:
+ return ONENAND_WP_US;
+
+ default:
+ break;
+ }
+
+ /* BootRAM access control */
+ if (reg < ONENAND_DATARAM && onenand->bootram_command) {
+ if (word_addr == 0)
+ return readl(&onenand->reg->MANUFACT_ID);
+ if (word_addr == 1)
+ return readl(&onenand->reg->DEVICE_ID);
+ if (word_addr == 2)
+ return readl(&onenand->reg->FLASH_VER_ID);
+ }
+
+ value = s3c_read_cmd(CMD_MAP_11(word_addr)) & 0xffff;
+ printk(KERN_INFO "s3c_onenand_readw: Illegal access"
+ " at reg 0x%x, value 0x%x\n", word_addr, value);
+ return value;
+}
+
+static void s3c_onenand_writew(unsigned short value, void __iomem *addr)
+{
+ struct onenand_chip *this = onenand->mtd->priv;
+ int reg = addr - this->base;
+ int word_addr = reg >> 1;
+
+ /* It's used for probing time */
+ switch (reg) {
+ case ONENAND_REG_SYS_CFG1:
+ writel(value, &onenand->reg->MEM_CFG);
+ return;
+
+ case ONENAND_REG_START_ADDRESS1:
+ case ONENAND_REG_START_ADDRESS2:
+ return;
+
+ /* Lock/lock-tight/unlock/unlock_all */
+ case ONENAND_REG_START_BLOCK_ADDRESS:
+ return;
+
+ default:
+ break;
+ }
+
+ /* BootRAM access control */
+ if (reg < ONENAND_DATARAM) {
+ if (value == ONENAND_CMD_READID) {
+ onenand->bootram_command = 1;
+ return;
+ }
+ if (value == ONENAND_CMD_RESET) {
+ writel(ONENAND_MEM_RESET_COLD,
+ &onenand->reg->MEM_RESET);
+ onenand->bootram_command = 0;
+ return;
+ }
+ }
+
+ printk(KERN_INFO "s3c_onenand_writew: Illegal access"
+ " at reg 0x%x, value 0x%x\n", word_addr, value);
+
+ s3c_write_cmd(value, CMD_MAP_11(word_addr));
+}
+
+static int s3c_onenand_wait(struct mtd_info *mtd, int state)
+{
+ unsigned int flags = INT_ACT;
+ unsigned int stat, ecc;
+ unsigned long timeout = 0x100000;
+
+ switch (state) {
+ case FL_READING:
+ flags |= BLK_RW_CMP | LOAD_CMP;
+ break;
+ case FL_WRITING:
+ flags |= BLK_RW_CMP | PGM_CMP;
+ break;
+ case FL_ERASING:
+ flags |= BLK_RW_CMP | ERS_CMP;
+ break;
+ case FL_LOCKING:
+ flags |= BLK_RW_CMP;
+ break;
+ default:
+ break;
+ }
+
+ while (timeout--) {
+ stat = readl(&onenand->reg->INT_ERR_STAT);
+ if (stat & flags)
+ break;
+ }
+
+ /* To get correct interrupt status in timeout case */
+ stat = readl(&onenand->reg->INT_ERR_STAT);
+ writel(stat, &onenand->reg->INT_ERR_ACK);
+
+ /*
+ * In the Spec. it checks the controller status first
+ * However if you get the correct information in case of
+ * power off recovery (POR) test, it should read ECC status first
+ */
+ if (stat & LOAD_CMP) {
+ ecc = readl(&onenand->reg->ECC_ERR_STAT);
+ if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) {
+ printk(KERN_INFO "%s: ECC error = 0x%04x\n",
+ __func__, ecc);
+ mtd->ecc_stats.failed++;
+ return -EBADMSG;
+ }
+ }
+
+ if (stat & (LOCKED_BLK | ERS_FAIL | PGM_FAIL | LD_FAIL_ECC_ERR)) {
+ printk(KERN_INFO "%s: controller error = 0x%04x\n",
+ __func__, stat);
+ if (stat & LOCKED_BLK)
+ printk(KERN_INFO "%s: it's locked error = 0x%04x\n",
+ __func__, stat);
+
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int s3c_onenand_command(struct mtd_info *mtd, int cmd,
+ loff_t addr, size_t len)
+{
+ struct onenand_chip *this = mtd->priv;
+ unsigned int *m, *s;
+ int fba, fpa, fsa = 0;
+ unsigned int mem_addr;
+ int i, mcount, scount;
+ int index;
+
+ fba = (int) (addr >> this->erase_shift);
+ fpa = (int) (addr >> this->page_shift);
+ fpa &= this->page_mask;
+
+ mem_addr = onenand->mem_addr(fba, fpa, fsa);
+
+ switch (cmd) {
+ case ONENAND_CMD_READ:
+ case ONENAND_CMD_READOOB:
+ case ONENAND_CMD_BUFFERRAM:
+ ONENAND_SET_NEXT_BUFFERRAM(this);
+ default:
+ break;
+ }
+
+ index = ONENAND_CURRENT_BUFFERRAM(this);
+
+ /*
+ * Emulate Two BufferRAMs and access with 4 bytes pointer
+ */
+ m = (unsigned int *) onenand->page_buf;
+ s = (unsigned int *) onenand->oob_buf;
+
+ if (index) {
+ m += (this->writesize >> 2);
+ s += (mtd->oobsize >> 2);
+ }
+
+ mcount = mtd->writesize >> 2;
+ scount = mtd->oobsize >> 2;
+
+ switch (cmd) {
+ case ONENAND_CMD_READ:
+ /* Main */
+ for (i = 0; i < mcount; i++)
+ *m++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
+ return 0;
+
+ case ONENAND_CMD_READOOB:
+ writel(TSRF, &onenand->reg->TRANS_SPARE);
+ /* Main */
+ for (i = 0; i < mcount; i++)
+ *m++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
+
+ /* Spare */
+ for (i = 0; i < scount; i++)
+ *s++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
+
+ writel(0, &onenand->reg->TRANS_SPARE);
+ return 0;
+
+ case ONENAND_CMD_PROG:
+ /* Main */
+ for (i = 0; i < mcount; i++)
+ s3c_write_cmd(*m++, CMD_MAP_01(mem_addr));
+ return 0;
+
+ case ONENAND_CMD_PROGOOB:
+ writel(TSRF, &onenand->reg->TRANS_SPARE);
+
+ /* Main - dummy write */
+ for (i = 0; i < mcount; i++)
+ s3c_write_cmd(0xffffffff, CMD_MAP_01(mem_addr));
+
+ /* Spare */
+ for (i = 0; i < scount; i++)
+ s3c_write_cmd(*s++, CMD_MAP_01(mem_addr));
+
+ writel(0, &onenand->reg->TRANS_SPARE);
+ return 0;
+
+ case ONENAND_CMD_UNLOCK_ALL:
+ s3c_write_cmd(ONENAND_UNLOCK_ALL, CMD_MAP_10(mem_addr));
+ return 0;
+
+ case ONENAND_CMD_ERASE:
+ s3c_write_cmd(ONENAND_ERASE_START, CMD_MAP_10(mem_addr));
+ return 0;
+
+ case ONENAND_CMD_MULTIBLOCK_ERASE:
+ s3c_write_cmd(ONENAND_MULTI_ERASE_SET, CMD_MAP_10(mem_addr));
+ return 0;
+
+ case ONENAND_CMD_ERASE_VERIFY:
+ s3c_write_cmd(ONENAND_ERASE_VERIFY, CMD_MAP_10(mem_addr));
+ return 0;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static unsigned char *s3c_get_bufferram(struct mtd_info *mtd, int area)
+{
+ struct onenand_chip *this = mtd->priv;
+ int index = ONENAND_CURRENT_BUFFERRAM(this);
+ unsigned char *p;
+
+ if (area == ONENAND_DATARAM) {
+ p = (unsigned char *) onenand->page_buf;
+ if (index == 1)
+ p += this->writesize;
+ } else {
+ p = (unsigned char *) onenand->oob_buf;
+ if (index == 1)
+ p += mtd->oobsize;
+ }
+
+ return p;
+}
+
+static int onenand_read_bufferram(struct mtd_info *mtd, loff_t addr, int area,
+ unsigned char *buffer, int offset,
+ size_t count)
+{
+ unsigned char *p;
+
+ p = s3c_get_bufferram(mtd, area);
+ memcpy(buffer, p + offset, count);
+ return 0;
+}
+
+static int onenand_write_bufferram(struct mtd_info *mtd, loff_t addr, int area,
+ const unsigned char *buffer, int offset,
+ size_t count)
+{
+ unsigned char *p;
+
+ p = s3c_get_bufferram(mtd, area);
+ memcpy(p + offset, buffer, count);
+ return 0;
+}
+
+static int s3c_onenand_bbt_wait(struct mtd_info *mtd, int state)
+{
+ struct samsung_onenand *reg = (struct samsung_onenand *)onenand->base;
+ unsigned int flags = INT_ACT | LOAD_CMP;
+ unsigned int stat;
+ unsigned long timeout = 0x10000;
+
+ while (timeout--) {
+ stat = readl(®->INT_ERR_STAT);
+ if (stat & flags)
+ break;
+ }
+ /* To get correct interrupt status in timeout case */
+ stat = readl(&onenand->reg->INT_ERR_STAT);
+ writel(stat, &onenand->reg->INT_ERR_ACK);
+
+ if (stat & LD_FAIL_ECC_ERR) {
+ s3c_onenand_reset();
+ return ONENAND_BBT_READ_ERROR;
+ }
+
+ if (stat & LOAD_CMP) {
+ int ecc = readl(&onenand->reg->ECC_ERR_STAT);
+ if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) {
+ s3c_onenand_reset();
+ return ONENAND_BBT_READ_ERROR;
+ }
+ }
+
+ return 0;
+}
+
+static void s3c_onenand_check_lock_status(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+ unsigned int block, end;
+ int tmp;
+
+ end = this->chipsize >> this->erase_shift;
+
+ for (block = 0; block < end; block++) {
+ tmp = s3c_read_cmd(CMD_MAP_01(onenand->mem_addr(block, 0, 0)));
+
+ if (readl(&onenand->reg->INT_ERR_STAT) & LOCKED_BLK) {
+ printf("block %d is write-protected!\n", block);
+ writel(LOCKED_BLK, &onenand->reg->INT_ERR_ACK);
+ }
+ }
+}
+
+static void s3c_onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs,
+ size_t len, int cmd)
+{
+ struct onenand_chip *this = mtd->priv;
+ int start, end, start_mem_addr, end_mem_addr;
+
+ start = ofs >> this->erase_shift;
+ start_mem_addr = onenand->mem_addr(start, 0, 0);
+ end = start + (len >> this->erase_shift) - 1;
+ end_mem_addr = onenand->mem_addr(end, 0, 0);
+
+ if (cmd == ONENAND_CMD_LOCK) {
+ s3c_write_cmd(ONENAND_LOCK_START, CMD_MAP_10(start_mem_addr));
+ s3c_write_cmd(ONENAND_LOCK_END, CMD_MAP_10(end_mem_addr));
+ } else {
+ s3c_write_cmd(ONENAND_UNLOCK_START, CMD_MAP_10(start_mem_addr));
+ s3c_write_cmd(ONENAND_UNLOCK_END, CMD_MAP_10(end_mem_addr));
+ }
+
+ this->wait(mtd, FL_LOCKING);
+}
+
+static void s3c_onenand_unlock_all(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+ loff_t ofs = 0;
+ size_t len = this->chipsize;
+
+ /* FIXME workaround */
+ this->subpagesize = mtd->writesize;
+ mtd->subpage_sft = 0;
+
+ if (this->options & ONENAND_HAS_UNLOCK_ALL) {
+ /* Write unlock command */
+ this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
+
+ /* No need to check return value */
+ this->wait(mtd, FL_LOCKING);
+
+ /* Workaround for all block unlock in DDP */
+ if (!ONENAND_IS_DDP(this)) {
+ s3c_onenand_check_lock_status(mtd);
+ return;
+ }
+
+ /* All blocks on another chip */
+ ofs = this->chipsize >> 1;
+ len = this->chipsize >> 1;
+ }
+
+ s3c_onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
+
+ s3c_onenand_check_lock_status(mtd);
+}
+
+#ifdef CONFIG_S3C64XX
+static void s3c_set_width_regs(struct onenand_chip *this)
+{
+ int dev_id, density;
+ int fba, fpa, fsa;
+ int dbs_dfs;
+
+ dev_id = DEVICE_ID0_REG;
+
+ density = (dev_id >> ONENAND_DEVICE_DENSITY_SHIFT) & 0xf;
+ dbs_dfs = !!(dev_id & ONENAND_DEVICE_IS_DDP);
+
+ fba = density + 7;
+ if (dbs_dfs)
+ fba--; /* Decrease the fba */
+ fpa = 6;
+ if (density >= ONENAND_DEVICE_DENSITY_512Mb)
+ fsa = 2;
+ else
+ fsa = 1;
+
+ DPRINTK("FBA %lu, FPA %lu, FSA %lu, DDP %lu",
+ FBA_WIDTH0_REG, FPA_WIDTH0_REG, FSA_WIDTH0_REG,
+ DDP_DEVICE_REG);
+
+ DPRINTK("mem_cfg0 0x%lx, sync mode %lu, "
+ "dev_page_size %lu, BURST LEN %lu",
+ MEM_CFG0_REG, SYNC_MODE_REG,
+ DEV_PAGE_SIZE_REG, BURST_LEN0_REG);
+
+ DEV_PAGE_SIZE_REG = 0x1;
+
+ FBA_WIDTH0_REG = fba;
+ FPA_WIDTH0_REG = fpa;
+ FSA_WIDTH0_REG = fsa;
+ DBS_DFS_WIDTH0_REG = dbs_dfs;
+}
+#endif
+
+void s3c_onenand_init(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+
+ onenand = malloc(sizeof(struct s3c_onenand));
+ if (!onenand)
+ return;
+
+ onenand->page_buf = malloc(SZ_4K * sizeof(char));
+ if (!onenand->page_buf)
+ return;
+ memset(onenand->page_buf, 0xFF, SZ_4K);
+
+ onenand->oob_buf = malloc(128 * sizeof(char));
+ if (!onenand->oob_buf)
+ return;
+ memset(onenand->oob_buf, 0xFF, 128);
+
+ onenand->mtd = mtd;
+
+#ifdef CONFIG_S5PC1XX
+ /* S5PC100 specific values */
+ onenand->base = (void *) 0xE7100000;
+ onenand->ahb_addr = (void *) 0xB0000000;
+ onenand->mem_addr = s5pc100_mem_addr;
+#else
+ onenand->base = (void *) 0x70100000;
+ onenand->ahb_addr = (void *) 0x20000000;
+ onenand->mem_addr = s3c64xx_mem_addr;
+#endif
+ onenand->reg = (struct samsung_onenand *)onenand->base;
+
+ this->read_word = s3c_onenand_readw;
+ this->write_word = s3c_onenand_writew;
+
+ this->wait = s3c_onenand_wait;
+ this->bbt_wait = s3c_onenand_bbt_wait;
+ this->unlock_all = s3c_onenand_unlock_all;
+ this->command = s3c_onenand_command;
+
+ this->read_bufferram = onenand_read_bufferram;
+ this->write_bufferram = onenand_write_bufferram;
+
+ this->options |= ONENAND_RUNTIME_BADBLOCK_CHECK;
+}
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index 06f7baf..9a6f317 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -135,6 +135,7 @@ struct onenand_chip {
#define ONENAND_HAS_CONT_LOCK (0x0001)
#define ONENAND_HAS_UNLOCK_ALL (0x0002)
#define ONENAND_HAS_2PLANE (0x0004)
+#define ONENAND_RUNTIME_BADBLOCK_CHECK (0x0200)
#define ONENAND_PAGEBUF_ALLOC (0x1000)
#define ONENAND_OOBBUF_ALLOC (0x2000)
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
index fc63380..07fed1c 100644
--- a/include/linux/mtd/onenand_regs.h
+++ b/include/linux/mtd/onenand_regs.h
@@ -121,6 +121,8 @@
#define ONENAND_CMD_LOCK_TIGHT (0x2C)
#define ONENAND_CMD_UNLOCK_ALL (0x27)
#define ONENAND_CMD_ERASE (0x94)
+#define ONENAND_CMD_MULTIBLOCK_ERASE (0x95)
+#define ONENAND_CMD_ERASE_VERIFY (0x71)
#define ONENAND_CMD_RESET (0xF0)
#define ONENAND_CMD_READID (0x90)
@@ -184,7 +186,9 @@
* ECC Status Reigser FF00h (R)
*/
#define ONENAND_ECC_1BIT (1 << 0)
+#define ONENAND_ECC_1BIT_ALL (0x5555)
#define ONENAND_ECC_2BIT (1 << 1)
#define ONENAND_ECC_2BIT_ALL (0xAAAA)
+#define ONENAND_ECC_4BIT_UNCORRECTABLE (0x1010)
#endif /* __ONENAND_REG_H */
diff --git a/include/linux/mtd/samsung_onenand.h b/include/linux/mtd/samsung_onenand.h
new file mode 100644
index 0000000..d389606
--- /dev/null
+++ b/include/linux/mtd/samsung_onenand.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2005-2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang(a)samsung.com>
+ * Kyungmin Park <kyungmin.park(a)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 __SAMSUNG_ONENAND_H__
+#define __SAMSUNG_ONENAND_H__
+
+#include <asm/hardware.h>
+
+/*
+ * OneNAND Controller
+ */
+
+#ifndef __ASSEMBLY__
+struct samsung_onenand {
+ unsigned long MEM_CFG; /* 0x0000 */
+ unsigned char res1[0xc];
+ unsigned long BURST_LEN; /* 0x0010 */
+ unsigned char res2[0xc];
+ unsigned long MEM_RESET; /* 0x0020 */
+ unsigned char res3[0xc];
+ unsigned long INT_ERR_STAT; /* 0x0030 */
+ unsigned char res4[0xc];
+ unsigned long INT_ERR_MASK; /* 0x0040 */
+ unsigned char res5[0xc];
+ unsigned long INT_ERR_ACK; /* 0x0050 */
+ unsigned char res6[0xc];
+ unsigned long ECC_ERR_STAT; /* 0x0060 */
+ unsigned char res7[0xc];
+ unsigned long MANUFACT_ID; /* 0x0070 */
+ unsigned char res8[0xc];
+ unsigned long DEVICE_ID; /* 0x0080 */
+ unsigned char res9[0xc];
+ unsigned long DATA_BUF_SIZE; /* 0x0090 */
+ unsigned char res10[0xc];
+ unsigned long BOOT_BUF_SIZE; /* 0x00A0 */
+ unsigned char res11[0xc];
+ unsigned long BUF_AMOUNT; /* 0x00B0 */
+ unsigned char res12[0xc];
+ unsigned long TECH; /* 0x00C0 */
+ unsigned char res13[0xc];
+ unsigned long FBA; /* 0x00D0 */
+ unsigned char res14[0xc];
+ unsigned long FPA; /* 0x00E0 */
+ unsigned char res15[0xc];
+ unsigned long FSA; /* 0x00F0 */
+ unsigned char res16[0x3c];
+ unsigned long SYNC_MODE; /* 0x0130 */
+ unsigned char res17[0xc];
+ unsigned long TRANS_SPARE; /* 0x0140 */
+ unsigned char res18[0x3c];
+ unsigned long ERR_PAGE_ADDR; /* 0x0180 */
+ unsigned char res19[0x1c];
+ unsigned long INT_PIN_EN; /* 0x01A0 */
+ unsigned char res20[0x1c];
+ unsigned long ACC_CLOCK; /* 0x01C0 */
+ unsigned char res21[0x1c];
+ unsigned long ERR_BLK_ADDR; /* 0x01E0 */
+ unsigned char res22[0xc];
+ unsigned long FLASH_VER_ID; /* 0x01F0 */
+ unsigned char res23[0x6c];
+ unsigned long WATCHDOG_CNT_LOW; /* 0x0260 */
+ unsigned char res24[0xc];
+ unsigned long WATCHDOG_CNT_HI; /* 0x0270 */
+ unsigned char res25[0xc];
+ unsigned long SYNC_WRITE; /* 0x0280 */
+ unsigned char res26[0x1c];
+ unsigned long COLD_RESET; /* 0x02A0 */
+ unsigned char res27[0xc];
+ unsigned long DDP_DEVICE; /* 0x02B0 */
+ unsigned char res28[0xc];
+ unsigned long MULTI_PLANE; /* 0x02C0 */
+ unsigned char res29[0x1c];
+ unsigned long TRANS_MODE; /* 0x02E0 */
+ unsigned char res30[0x1c];
+ unsigned long ECC_ERR_STAT2; /* 0x0300 */
+ unsigned char res31[0xc];
+ unsigned long ECC_ERR_STAT3; /* 0x0310 */
+ unsigned char res32[0xc];
+ unsigned long ECC_ERR_STAT4; /* 0x0320 */
+ unsigned char res33[0x1c];
+ unsigned long DEV_PAGE_SIZE; /* 0x0340 */
+ unsigned char res34[0x4c];
+ unsigned long INT_MON_STATUS; /* 0x0390 */
+};
+#endif
+
+#define ONENAND_MEM_RESET_HOT 0x3
+#define ONENAND_MEM_RESET_COLD 0x2
+#define ONENAND_MEM_RESET_WARM 0x1
+
+#define CACHE_OP_ERR (1 << 13)
+#define RST_CMP (1 << 12)
+#define RDY_ACT (1 << 11)
+#define INT_ACT (1 << 10)
+#define UNSUP_CMD (1 << 9)
+#define LOCKED_BLK (1 << 8)
+#define BLK_RW_CMP (1 << 7)
+#define ERS_CMP (1 << 6)
+#define PGM_CMP (1 << 5)
+#define LOAD_CMP (1 << 4)
+#define ERS_FAIL (1 << 3)
+#define PGM_FAIL (1 << 2)
+#define INT_TO (1 << 1)
+#define LD_FAIL_ECC_ERR (1 << 0)
+
+#define TSRF (1 << 0)
+
+/* common initialize function */
+extern void s3c_onenand_init(struct mtd_info *);
+
+#endif
--
1.5.4.3
6
12
This patch adds support for the Samsung s5pc100 and s5pc110
SoCs. The s5pc1xx SoC is an ARM Cortex A8 processor.
Signed-off-by: Minkyu Kang <mk7.kang(a)samsung.com>
Signed-off-by: HeungJun, Kim <riverful.kim(a)samsung.com>
---
cpu/arm_cortexa8/s5pc1xx/Makefile | 53 ++++++
cpu/arm_cortexa8/s5pc1xx/cache.c | 43 +++++
cpu/arm_cortexa8/s5pc1xx/clock.c | 302 ++++++++++++++++++++++++++++++
cpu/arm_cortexa8/s5pc1xx/cpu_info.c | 75 ++++++++
cpu/arm_cortexa8/s5pc1xx/reset.S | 47 +++++
cpu/arm_cortexa8/s5pc1xx/timer.c | 195 +++++++++++++++++++
include/asm-arm/arch-s5pc1xx/clk.h | 46 +++++
include/asm-arm/arch-s5pc1xx/clock.h | 100 ++++++++++
include/asm-arm/arch-s5pc1xx/cpu.h | 73 +++++++
include/asm-arm/arch-s5pc1xx/gpio.h | 127 +++++++++++++
include/asm-arm/arch-s5pc1xx/hardware.h | 63 ++++++
include/asm-arm/arch-s5pc1xx/i2c.h | 43 +++++
include/asm-arm/arch-s5pc1xx/interrupt.h | 40 ++++
include/asm-arm/arch-s5pc1xx/mem.h | 58 ++++++
include/asm-arm/arch-s5pc1xx/power.h | 42 ++++
include/asm-arm/arch-s5pc1xx/pwm.h | 65 +++++++
include/asm-arm/arch-s5pc1xx/uart.h | 53 ++++++
17 files changed, 1425 insertions(+), 0 deletions(-)
create mode 100644 cpu/arm_cortexa8/s5pc1xx/Makefile
create mode 100644 cpu/arm_cortexa8/s5pc1xx/cache.c
create mode 100644 cpu/arm_cortexa8/s5pc1xx/clock.c
create mode 100644 cpu/arm_cortexa8/s5pc1xx/cpu_info.c
create mode 100644 cpu/arm_cortexa8/s5pc1xx/reset.S
create mode 100644 cpu/arm_cortexa8/s5pc1xx/timer.c
create mode 100644 include/asm-arm/arch-s5pc1xx/clk.h
create mode 100644 include/asm-arm/arch-s5pc1xx/clock.h
create mode 100644 include/asm-arm/arch-s5pc1xx/cpu.h
create mode 100644 include/asm-arm/arch-s5pc1xx/gpio.h
create mode 100644 include/asm-arm/arch-s5pc1xx/hardware.h
create mode 100644 include/asm-arm/arch-s5pc1xx/i2c.h
create mode 100644 include/asm-arm/arch-s5pc1xx/interrupt.h
create mode 100644 include/asm-arm/arch-s5pc1xx/mem.h
create mode 100644 include/asm-arm/arch-s5pc1xx/power.h
create mode 100644 include/asm-arm/arch-s5pc1xx/pwm.h
create mode 100644 include/asm-arm/arch-s5pc1xx/uart.h
diff --git a/cpu/arm_cortexa8/s5pc1xx/Makefile b/cpu/arm_cortexa8/s5pc1xx/Makefile
new file mode 100644
index 0000000..e08d9d8
--- /dev/null
+++ b/cpu/arm_cortexa8/s5pc1xx/Makefile
@@ -0,0 +1,53 @@
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd(a)denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg(a)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
+
+COBJS += cache.o
+COBJS += clock.o
+COBJS += cpu_info.o
+COBJS += timer.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm_cortexa8/s5pc1xx/cache.c b/cpu/arm_cortexa8/s5pc1xx/cache.c
new file mode 100644
index 0000000..8652a45
--- /dev/null
+++ b/cpu/arm_cortexa8/s5pc1xx/cache.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang(a)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/cache.h>
+
+void l2_cache_enable(void)
+{
+ unsigned long i;
+
+ __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i));
+ __asm__ __volatile__("orr %0, %0, #0x2":"=r"(i));
+ __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i));
+}
+
+void l2_cache_disable(void)
+{
+ unsigned long i;
+
+ __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i));
+ __asm__ __volatile__("bic %0, %0, #0x2":"=r"(i));
+ __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i));
+}
diff --git a/cpu/arm_cortexa8/s5pc1xx/clock.c b/cpu/arm_cortexa8/s5pc1xx/clock.c
new file mode 100644
index 0000000..da56fda
--- /dev/null
+++ b/cpu/arm_cortexa8/s5pc1xx/clock.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang(a)samsung.com>
+ * Heungjun Kim <riverful.kim(a)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>
+#include <asm/arch/clock.h>
+
+#define APLL 0
+#define MPLL 1
+#define EPLL 2
+#define HPLL 3
+#define VPLL 4
+
+#ifndef CONFIG_SYS_CLK_FREQ_C100
+#define CONFIG_SYS_CLK_FREQ_C100 12000000
+#endif
+#ifndef CONFIG_SYS_CLK_FREQ_C110
+#define CONFIG_SYS_CLK_FREQ_C110 24000000
+#endif
+
+/*
+ * CONFIG_SYS_CLK_FREQ_C1xx should be defined as the input frequency
+ *
+ * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of
+ * the specified bus in HZ
+ */
+unsigned long get_pll_clk(int pllreg)
+{
+ struct s5pc100_clock *clk_c100 =
+ (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE;
+ struct s5pc110_clock *clk_c110 =
+ (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE;
+ unsigned long r, m, p, s, mask, fout;
+ unsigned int freq;
+
+ switch (pllreg) {
+ case APLL:
+ if (cpu_is_s5pc110())
+ r = readl(&clk_c110->APLL_CON);
+ else
+ r = readl(&clk_c100->APLL_CON);
+ break;
+ case MPLL:
+ if (cpu_is_s5pc110())
+ r = readl(&clk_c110->MPLL_CON);
+ else
+ r = readl(&clk_c100->MPLL_CON);
+ break;
+ case EPLL:
+ if (cpu_is_s5pc110())
+ r = readl(&clk_c110->EPLL_CON);
+ else
+ r = readl(&clk_c100->EPLL_CON);
+ break;
+ case HPLL:
+ if (cpu_is_s5pc110()) {
+ puts("s5pc110 don't use HPLL\n");
+ return 0;
+ }
+ r = readl(&clk_c100->HPLL_CON);
+ break;
+ case VPLL:
+ if (cpu_is_s5pc100()) {
+ puts("s5pc100 don't use VPLL\n");
+ return 0;
+ }
+ r = readl(&clk_c110->VPLL_CON);
+ break;
+ default:
+ printf("Unsupported PLL (%d)\n", pllreg);
+ return 0;
+ }
+
+ if (cpu_is_s5pc110()) {
+ /*
+ * 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;
+ } else {
+ /*
+ * APLL_CON: MIDV [25:16]
+ * MPLL_CON: MIDV [23:16]
+ * EPLL_CON: MIDV [23:16]
+ * HPLL_CON: MIDV [23:16]
+ */
+ if (pllreg == APLL)
+ mask = 0x3ff;
+ else
+ mask = 0x0ff;
+ }
+ m = (r >> 16) & mask;
+
+ /* PDIV [13:8] */
+ p = (r >> 8) & 0x3f;
+ /* SDIV [2:0] */
+ s = r & 0x7;
+
+ if (cpu_is_s5pc110()) {
+ freq = CONFIG_SYS_CLK_FREQ_C110;
+ 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)));
+ } else {
+ /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
+ freq = CONFIG_SYS_CLK_FREQ_C100;
+ fout = m * (freq / (p * (1 << s)));
+ }
+
+ return fout;
+}
+
+/* return ARMCORE frequency */
+unsigned long get_arm_clk(void)
+{
+ struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE;
+ unsigned long div;
+ unsigned long dout_apll, armclk;
+ unsigned int apll_ratio, arm_ratio;
+
+ div = readl(&clk->DIV0);
+ if (cpu_is_s5pc110()) {
+ /* ARM_RATIO: don't use */
+ arm_ratio = 0;
+ /* APLL_RATIO: [2:0] */
+ apll_ratio = div & 0x7;
+ } else {
+ /* ARM_RATIO: [6:4] */
+ arm_ratio = (div >> 4) & 0x7;
+ /* APLL_RATIO: [0] */
+ apll_ratio = div & 0x1;
+ }
+
+ dout_apll = get_pll_clk(APLL) / (apll_ratio + 1);
+ armclk = dout_apll / (arm_ratio + 1);
+
+ return armclk;
+}
+
+/* return FCLK frequency */
+unsigned long get_fclk(void)
+{
+ return get_pll_clk(APLL);
+}
+
+/* return MCLK frequency */
+unsigned long get_mclk(void)
+{
+ return get_pll_clk(MPLL);
+}
+
+/* s5pc100: return HCLKD0 frequency */
+unsigned long get_hclk(void)
+{
+ struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE;
+ unsigned long hclkd0;
+ uint div, d0_bus_ratio;
+
+ div = readl(&clk->DIV0);
+ /* D0_BUS_RATIO: [10:8] */
+ d0_bus_ratio = (div >> 8) & 0x7;
+
+ hclkd0 = get_arm_clk() / (d0_bus_ratio + 1);
+
+ return hclkd0;
+}
+
+/* s5pc100: return PCLKD0 frequency */
+unsigned long get_pclkd0(void)
+{
+ struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE;
+ unsigned long pclkd0;
+ uint div, pclkd0_ratio;
+
+ div = readl(&clk->DIV0);
+ /* PCLKD0_RATIO: [14:12] */
+ pclkd0_ratio = (div >> 12) & 0x7;
+
+ pclkd0 = get_hclk() / (pclkd0_ratio + 1);
+
+ return pclkd0;
+}
+
+/* s5pc100: return PCLKD1 frequency */
+unsigned long get_pclkd1(void)
+{
+ struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE;
+ unsigned long d1_bus, pclkd1;
+ uint div, d1_bus_ratio, pclkd1_ratio;
+
+ div = readl(&clk->DIV0);
+ /* D1_BUS_RATIO: [14:12] */
+ d1_bus_ratio = (div >> 12) & 0x7;
+ /* PCLKD1_RATIO: [18:16] */
+ pclkd1_ratio = (div >> 16) & 0x7;
+
+ /* ASYNC Mode */
+ d1_bus = get_pll_clk(MPLL) / (d1_bus_ratio + 1);
+ pclkd1 = d1_bus / (pclkd1_ratio + 1);
+
+ return pclkd1;
+}
+
+/* s5pc110: return HCLKs frequency */
+unsigned long get_hclk_sys(int dom)
+{
+ struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE;
+ unsigned long hclk;
+ unsigned int div;
+ unsigned int offset;
+ unsigned int hclk_sys_ratio;
+
+ if (dom == CLK_M)
+ return get_hclk();
+
+ div = readl(&clk->DIV0);
+
+ /*
+ * HCLK_MSYS_RATIO: [10:8]
+ * HCLK_DSYS_RATIO: [19:16]
+ * HCLK_PSYS_RATIO: [27:24]
+ */
+ offset = 8 + (dom << 0x3);
+
+ hclk_sys_ratio = (div >> offset) & 0xf;
+
+ hclk = get_pll_clk(MPLL) / (hclk_sys_ratio + 1);
+
+ return hclk;
+}
+
+/* s5pc110: return PCLKs frequency */
+unsigned long get_pclk_sys(int dom)
+{
+ struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE;
+ unsigned long pclk;
+ unsigned int div;
+ unsigned int offset;
+ unsigned int pclk_sys_ratio;
+
+ div = readl(&clk->DIV0);
+
+ /*
+ * PCLK_MSYS_RATIO: [14:12]
+ * PCLK_DSYS_RATIO: [22:20]
+ * PCLK_PSYS_RATIO: [30:28]
+ */
+ offset = 12 + (dom << 0x3);
+
+ pclk_sys_ratio = (div >> offset) & 0x7;
+
+ pclk = get_hclk_sys(dom) / (pclk_sys_ratio + 1);
+
+ return pclk;
+}
+
+/* return peripheral clock */
+unsigned long get_pclk(void)
+{
+ if (cpu_is_s5pc110())
+ return get_pclk_sys(CLK_P);
+ else
+ return get_pclkd1();
+}
+
+/* return UCLK frequency */
+unsigned long get_uclk(void)
+{
+ return get_pll_clk(EPLL);
+}
diff --git a/cpu/arm_cortexa8/s5pc1xx/cpu_info.c b/cpu/arm_cortexa8/s5pc1xx/cpu_info.c
new file mode 100644
index 0000000..eacacc8
--- /dev/null
+++ b/cpu/arm_cortexa8/s5pc1xx/cpu_info.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang(a)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 s5pc100 */
+unsigned int s5pc1xx_cpu_id = 0xC100;
+
+#ifdef CONFIG_ARCH_CPU_INIT
+int arch_cpu_init(void)
+{
+ s5pc1xx_cpu_id = readl(S5PC1XX_PRO_ID);
+ s5pc1xx_cpu_id = 0xC000 | ((s5pc1xx_cpu_id & 0x00FFF000) >> 12);
+
+ return 0;
+}
+#endif
+
+u32 get_device_type(void)
+{
+ return s5pc1xx_cpu_id;
+}
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+ char buf[32];
+
+ printf("CPU:\tS5P%X@%sMHz\n",
+ s5pc1xx_cpu_id, strmhz(buf, get_arm_clk()));
+ if (cpu_is_s5pc110()) {
+ printf("\tAPLL = %s MHz, ", strmhz(buf, get_fclk()));
+ printf("MPLL = %s MHz, ", strmhz(buf, get_mclk()));
+ printf("EPLL = %s MHz\n", strmhz(buf, get_uclk()));
+
+ printf("\tHclk: Msys %s MHz, ",
+ strmhz(buf, get_hclk_sys(CLK_M)));
+ printf("Dsys %7s MHz, ", strmhz(buf, get_hclk_sys(CLK_D)));
+ printf("Psys %7s MHz\n", strmhz(buf, get_hclk_sys(CLK_P)));
+
+ printf("\tPclk: Msys %s MHz, ",
+ strmhz(buf, get_pclk_sys(CLK_M)));
+ printf("Dsys %7s MHz, ", strmhz(buf, get_pclk_sys(CLK_D)));
+ printf("Psys %7s MHz\n", strmhz(buf, get_pclk_sys(CLK_P)));
+ } else {
+ printf("\tFclk = %s MHz\n", strmhz(buf, get_fclk()));
+ printf("\tHclkD0 = %s MHz\n", strmhz(buf, get_hclk()));
+ printf("\tPclkD0 = %s MHz\n", strmhz(buf, get_pclkd0()));
+ printf("\tPclkD1 = %s MHz\n", strmhz(buf, get_pclkd1()));
+ }
+
+ return 0;
+}
+#endif
diff --git a/cpu/arm_cortexa8/s5pc1xx/reset.S b/cpu/arm_cortexa8/s5pc1xx/reset.S
new file mode 100644
index 0000000..7f6ff9c
--- /dev/null
+++ b/cpu/arm_cortexa8/s5pc1xx/reset.S
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009 Samsung Electronics.
+ * Minkyu Kang <mk7.kang(a)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 S5PC100_SWRESET 0xE0200000
+#define S5PC110_SWRESET 0xE0102000
+
+.globl reset_cpu
+reset_cpu:
+ ldr r1, =S5PC1XX_PRO_ID
+ ldr r2, [r1]
+ ldr r4, =0x00010000
+ and r4, r2, r4
+ cmp r4, #0
+ bne 110f
+ /* S5PC100 */
+ ldr r1, =S5PC100_SWRESET
+ ldr r2, =0xC100
+ b 200f
+110: /* S5PC110 */
+ ldr r1, =S5PC110_SWRESET
+ mov r2, #1
+200:
+ str r2, [r1]
+_loop_forever:
+ b _loop_forever
diff --git a/cpu/arm_cortexa8/s5pc1xx/timer.c b/cpu/arm_cortexa8/s5pc1xx/timer.c
new file mode 100644
index 0000000..f3d94b8
--- /dev/null
+++ b/cpu/arm_cortexa8/s5pc1xx/timer.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Heungjun Kim <riverful.kim(a)samsung.com>
+ * Inki Dae <inki.dae(a)samsung.com>
+ * Minkyu Kang <mk7.kang(a)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 s5pc1xx_timer *s5pc1xx_get_base_timer(void)
+{
+ if (cpu_is_s5pc110())
+ return (struct s5pc1xx_timer *)S5PC110_TIMER_BASE;
+ else
+ return (struct s5pc1xx_timer *)S5PC100_TIMER_BASE;
+}
+
+int timer_init(void)
+{
+ struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer();
+ u32 val;
+
+ /*
+ * @ PWM Timer 4
+ * Timer Freq(HZ) =
+ * PCLK / { (prescaler_value + 1) * (divider_value) }
+ */
+
+ /* set prescaler : 16 */
+ /* set divider : 2 */
+ writel((PRESCALER_1 & 0xff) << 8, &timer->TCFG0);
+ writel((MUX_DIV_2 & 0xf) << MUX4_DIV_SHIFT, &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)) |
+ S5PC1XX_TCON4_AUTO_RELOAD;
+
+ /* auto reload & manual update */
+ writel(val | S5PC1XX_TCON4_UPDATE, &timer->TCON);
+
+ /* start PWM timer 4 */
+ writel(val | S5PC1XX_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;
+
+ 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(0);
+
+ /* if setting this fordward will roll time stamp */
+ /* reset "advancing" timestamp to 0, set lastdec value */
+ /* else, set advancing stamp wake up time */
+ if ((tmo + tmp + 1) < tmp)
+ reset_timer_masked();
+ else
+ tmo += tmp;
+
+ /* loop till event */
+ while (get_timer_masked() < tmo)
+ ; /* nop */
+}
+
+void reset_timer_masked(void)
+{
+ struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer();
+
+ /* reset time */
+ lastdec = readl(&timer->TCNTO4);
+ timestamp = 0;
+}
+
+unsigned long get_timer_masked(void)
+{
+ struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer();
+ unsigned long now = readl(&timer->TCNTO4);
+
+ if (lastdec >= now)
+ timestamp += lastdec - now;
+ else
+ timestamp += lastdec + count_value - now;
+
+ lastdec = now;
+
+ return timestamp;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+unsigned long get_tbclk(void)
+{
+ return CONFIG_SYS_HZ;
+}
diff --git a/include/asm-arm/arch-s5pc1xx/clk.h b/include/asm-arm/arch-s5pc1xx/clk.h
new file mode 100644
index 0000000..9c13a71
--- /dev/null
+++ b/include/asm-arm/arch-s5pc1xx/clk.h
@@ -0,0 +1,46 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang(a)samsung.com>
+ * Heungjun Kim <riverful.kim(a)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_
+
+unsigned long get_pll_clk(int pllreg);
+unsigned long get_arm_clk(void);
+unsigned long get_fclk(void);
+unsigned long get_mclk(void);
+unsigned long get_hclk(void);
+unsigned long get_pclk(void);
+unsigned long get_uclk(void);
+
+/*s5pc110 */
+#define CLK_M 0
+#define CLK_D 1
+#define CLK_P 2
+
+unsigned long get_hclk_sys(int dom);
+unsigned long get_pclk_sys(int dom);
+
+/* s5pc100 */
+unsigned long get_pclkd0(void);
+unsigned long get_pclkd1(void);
+
+#endif
diff --git a/include/asm-arm/arch-s5pc1xx/clock.h b/include/asm-arm/arch-s5pc1xx/clock.h
new file mode 100644
index 0000000..f11c9ce
--- /dev/null
+++ b/include/asm-arm/arch-s5pc1xx/clock.h
@@ -0,0 +1,100 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang(a)samsung.com>
+ * Heungjun Kim <riverful.kim(a)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_
+
+/*
+ * Clock control
+ */
+
+/* Clock Register */
+
+#ifndef __ASSEMBLY__
+struct s5pc100_clock {
+ unsigned long APLL_LOCK;
+ unsigned long MPLL_LOCK;
+ unsigned long EPLL_LOCK;
+ unsigned long HPLL_LOCK;
+ unsigned char res1[0xf0];
+ unsigned long APLL_CON;
+ unsigned long MPLL_CON;
+ unsigned long EPLL_CON;
+ unsigned long HPLL_CON;
+ unsigned char res2[0xf0];
+ unsigned long SRC0;
+ unsigned long SRC1;
+ unsigned long SRC2;
+ unsigned long SRC3;
+ unsigned char res3[0xf0];
+ unsigned long DIV0;
+ unsigned long DIV1;
+ unsigned long DIV2;
+ unsigned long DIV3;
+ unsigned long DIV4;
+ unsigned char res4[0x1ec];
+ unsigned long GATE_D00;
+ unsigned long GATE_D01;
+ unsigned long GATE_D02;
+ unsigned char res5[0x54];
+ unsigned long GATE_SCLK0;
+ unsigned long GATE_SCLK1;
+};
+
+struct s5pc110_clock {
+ unsigned long APLL_LOCK;
+ unsigned char res1[0x4];
+ unsigned long MPLL_LOCK;
+ unsigned char res2[0x4];
+ unsigned long EPLL_LOCK;
+ unsigned char res3[0xc];
+ unsigned long VPLL_LOCK;
+ unsigned char res4[0xdc];
+ unsigned long APLL_CON;
+ unsigned char res5[0x4];
+ unsigned long MPLL_CON;
+ unsigned char res6[0x4];
+ unsigned long EPLL_CON;
+ unsigned char res7[0xc];
+ unsigned long VPLL_CON;
+ unsigned char res8[0xdc];
+ unsigned long SRC0;
+ unsigned long SRC1;
+ unsigned long SRC2;
+ unsigned long SRC3;
+ unsigned char res9[0xf0];
+ unsigned long DIV0;
+ unsigned long DIV1;
+ unsigned long DIV2;
+ unsigned long DIV3;
+ unsigned long DIV4;
+ unsigned char res10[0x1ec];
+ unsigned long GATE_D00;
+ unsigned long GATE_D01;
+ unsigned long GATE_D02;
+ unsigned char res11[0x54];
+ unsigned long GATE_SCLK0;
+ unsigned long GATE_SCLK1;
+};
+#endif
+
+#endif
diff --git a/include/asm-arm/arch-s5pc1xx/cpu.h b/include/asm-arm/arch-s5pc1xx/cpu.h
new file mode 100644
index 0000000..c7d7183
--- /dev/null
+++ b/include/asm-arm/arch-s5pc1xx/cpu.h
@@ -0,0 +1,73 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang(a)samsung.com>
+ * Heungjun Kim <riverful.kim(a)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 _S5PC1XX_CPU_H
+#define _S5PC1XX_CPU_H
+
+#include <asm/hardware.h>
+
+#define S5PC1XX_ADDR_BASE 0xe0000000
+#define S5P_ADDR(x) (S5PC1XX_ADDR_BASE + (x))
+
+#define S5PC1XX_CLOCK_BASE 0xE0100000
+#define S5P_PA_CLK_OTHERS S5P_ADDR(0x00200000) /* Clock Others Base */
+
+/* Note that write the macro by address order */
+#define S5PC100_VIC0_BASE 0xE4000000
+#define S5PC100_VIC1_BASE 0xE4100000
+#define S5PC100_VIC2_BASE 0xE4200000
+#define S5PC100_SROMC_BASE 0xE7000000
+#define S5PC100_ONENAND_BASE 0xE7100000
+#define S5PC100_WATCHDOG_BASE 0xEA200000
+
+#define S5PC110_WATCHDOG_BASE 0xE2700000
+#define S5PC110_SROMC_BASE 0xE8000000
+#define S5PC110_VIC0_BASE 0xF2000000
+#define S5PC110_VIC1_BASE 0xF2100000
+#define S5PC110_VIC2_BASE 0xF2200000
+#define S5PC110_VIC3_BASE 0xF2300000
+
+/*
+ * Chip ID
+ */
+#define S5PC1XX_CHIP_ID(x) (0xE0000000 + (x))
+#define S5PC1XX_PRO_ID S5PC1XX_CHIP_ID(0)
+#define S5PC1XX_OMR S5PC1XX_CHIP_ID(4)
+
+#ifndef __ASSEMBLY__
+/* CPU detection macros */
+extern unsigned int s5pc1xx_cpu_id;
+
+#define IS_SAMSUNG_TYPE(type, id) \
+static inline int is_##type(void) \
+{ \
+ return (s5pc1xx_cpu_id == (id)) ? 1 : 0; \
+}
+
+IS_SAMSUNG_TYPE(s5pc100, 0xc100)
+IS_SAMSUNG_TYPE(s5pc110, 0xc110)
+
+#define cpu_is_s5pc100() is_s5pc100()
+#define cpu_is_s5pc110() is_s5pc110()
+#endif
+
+#endif /* _S5PC1XX_CPU_H */
diff --git a/include/asm-arm/arch-s5pc1xx/gpio.h b/include/asm-arm/arch-s5pc1xx/gpio.h
new file mode 100644
index 0000000..26d0950
--- /dev/null
+++ b/include/asm-arm/arch-s5pc1xx/gpio.h
@@ -0,0 +1,127 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang(a)samsung.com>
+ * Heungjun Kim <riverful.kim(a)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 __S5PC1XX_GPIO_H
+#define __S5PC1XX_GPIO_H
+
+/* GPIO Bank Base */
+#define S5PC100_GPIO_BASE(x) (0xE0300000 + (x))
+#define S5PC110_GPIO_BASE(x) (0xE0200000 + (x))
+
+/* S5PC100 bank offset */
+#define S5PC100_GPIO_A0_OFFSET 0x000
+#define S5PC100_GPIO_A1_OFFSET 0x020
+#define S5PC100_GPIO_B_OFFSET 0x040
+#define S5PC100_GPIO_C_OFFSET 0x060
+#define S5PC100_GPIO_D_OFFSET 0x080
+#define S5PC100_GPIO_E0_OFFSET 0x0A0
+#define S5PC100_GPIO_E1_OFFSET 0x0C0
+#define S5PC100_GPIO_F0_OFFSET 0x0E0
+#define S5PC100_GPIO_F1_OFFSET 0x100
+#define S5PC100_GPIO_F2_OFFSET 0x120
+#define S5PC100_GPIO_F3_OFFSET 0x140
+#define S5PC100_GPIO_G0_OFFSET 0x160
+#define S5PC100_GPIO_G1_OFFSET 0x180
+#define S5PC100_GPIO_G2_OFFSET 0x1A0
+#define S5PC100_GPIO_G3_OFFSET 0x1C0
+#define S5PC100_GPIO_I_OFFSET 0x1E0
+#define S5PC100_GPIO_J0_OFFSET 0x200
+#define S5PC100_GPIO_J1_OFFSET 0x220
+#define S5PC100_GPIO_J2_OFFSET 0x240
+#define S5PC100_GPIO_J3_OFFSET 0x260
+#define S5PC100_GPIO_J4_OFFSET 0x280
+#define S5PC100_GPIO_K0_OFFSET 0x2A0
+#define S5PC100_GPIO_K1_OFFSET 0x2C0
+#define S5PC100_GPIO_K2_OFFSET 0x2E0
+#define S5PC100_GPIO_K3_OFFSET 0x300
+#define S5PC100_GPIO_L0_OFFSET 0x320
+#define S5PC100_GPIO_L1_OFFSET 0x340
+#define S5PC100_GPIO_L2_OFFSET 0x360
+#define S5PC100_GPIO_L3_OFFSET 0x380
+#define S5PC100_GPIO_L4_OFFSET 0x3A0
+#define S5PC100_GPIO_H0_OFFSET 0xC00
+#define S5PC100_GPIO_H1_OFFSET 0xC20
+#define S5PC100_GPIO_H2_OFFSET 0xC40
+#define S5PC100_GPIO_H3_OFFSET 0xC60
+
+/* S5PC110 bank offset */
+#define S5PC110_GPIO_A0_OFFSET 0x000
+#define S5PC110_GPIO_A1_OFFSET 0x020
+#define S5PC110_GPIO_B_OFFSET 0x040
+#define S5PC110_GPIO_C0_OFFSET 0x060
+#define S5PC110_GPIO_C1_OFFSET 0x080
+#define S5PC110_GPIO_D0_OFFSET 0x0A0
+#define S5PC110_GPIO_D1_OFFSET 0x0C0
+#define S5PC110_GPIO_E0_OFFSET 0x0E0
+#define S5PC110_GPIO_E1_OFFSET 0x110
+#define S5PC110_GPIO_F0_OFFSET 0x120
+#define S5PC110_GPIO_F1_OFFSET 0x140
+#define S5PC110_GPIO_F2_OFFSET 0x160
+#define S5PC110_GPIO_F3_OFFSET 0x180
+#define S5PC110_GPIO_G0_OFFSET 0x1A0
+#define S5PC110_GPIO_G1_OFFSET 0x1C0
+#define S5PC110_GPIO_G2_OFFSET 0x1E0
+#define S5PC110_GPIO_G3_OFFSET 0x200
+#define S5PC110_GPIO_I_OFFSET 0x220
+#define S5PC110_GPIO_J0_OFFSET 0x240
+#define S5PC110_GPIO_J1_OFFSET 0x260
+#define S5PC110_GPIO_J2_OFFSET 0x280
+#define S5PC110_GPIO_J3_OFFSET 0x2A0
+#define S5PC110_GPIO_J4_OFFSET 0x2C0
+#define S5PC110_GPIO_MP0_1_OFFSET 0x2E0
+#define S5PC110_GPIO_MP0_2_OFFSET 0x300
+#define S5PC110_GPIO_MP0_3_OFFSET 0x320
+#define S5PC110_GPIO_MP0_4_OFFSET 0x340
+#define S5PC110_GPIO_MP0_5_OFFSET 0x360
+#define S5PC110_GPIO_MP0_6_OFFSET 0x380
+#define S5PC110_GPIO_MP0_7_OFFSET 0x3A0
+#define S5PC110_GPIO_MP1_0_OFFSET 0x3C0
+#define S5PC110_GPIO_MP1_1_OFFSET 0x3E0
+#define S5PC110_GPIO_MP1_2_OFFSET 0x410
+#define S5PC110_GPIO_MP1_3_OFFSET 0x420
+#define S5PC110_GPIO_MP1_4_OFFSET 0x440
+#define S5PC110_GPIO_MP1_5_OFFSET 0x460
+#define S5PC110_GPIO_MP1_6_OFFSET 0x480
+#define S5PC110_GPIO_MP1_7_OFFSET 0x4A0
+#define S5PC110_GPIO_MP1_8_OFFSET 0x4C0
+#define S5PC110_GPIO_MP2_0_OFFSET 0x4E0
+#define S5PC110_GPIO_MP2_1_OFFSET 0x510
+#define S5PC110_GPIO_MP2_2_OFFSET 0x520
+#define S5PC110_GPIO_MP2_3_OFFSET 0x540
+#define S5PC110_GPIO_MP2_4_OFFSET 0x560
+#define S5PC110_GPIO_MP2_5_OFFSET 0x580
+#define S5PC110_GPIO_MP2_6_OFFSET 0x5A0
+#define S5PC110_GPIO_MP2_7_OFFSET 0x5C0
+#define S5PC110_GPIO_MP2_8_OFFSET 0x5E0
+#define S5PC110_GPIO_H0_OFFSET 0xC00
+#define S5PC110_GPIO_H1_OFFSET 0xC20
+#define S5PC110_GPIO_H2_OFFSET 0xC40
+#define S5PC110_GPIO_H3_OFFSET 0xC60
+
+/* GPIO bank Offset */
+#define S5PC1XX_GPIO_CON_OFFSET 0x0
+#define S5PC1XX_GPIO_DAT_OFFSET 0x4
+#define S5PC1XX_GPIO_PULL_OFFSET 0x8
+#define S5PC1XX_GPIO_DRV_OFFSET 0xc
+#define S5PC1XX_GPIO_PDNCON_OFFSET 0x10
+#define S5PC1XX_GPIO_PDNPULL_OFFSET 0x14
+
+#endif
diff --git a/include/asm-arm/arch-s5pc1xx/hardware.h b/include/asm-arm/arch-s5pc1xx/hardware.h
new file mode 100644
index 0000000..ca95c3d
--- /dev/null
+++ b/include/asm-arm/arch-s5pc1xx/hardware.h
@@ -0,0 +1,63 @@
+/*
+ * Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg(a)denx.de>
+ *
+ * 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 _ARCH_HARDWARE_H_
+#define _ARCH_HARDWARE_H_
+
+#include <asm/sizes.h>
+
+#ifndef __ASSEMBLY__
+#define UData(Data) ((unsigned long)(Data))
+
+#define __REG(x) (*(vu_long *)(x))
+#define __REGl(x) (*(vu_long *)(x))
+#define __REGw(x) (*(vu_short *)(x))
+#define __REGb(x) (*(vu_char *)(x))
+#define __REG2(x, y) (*(vu_long *)((x) + (y)))
+#else
+#define UData(Data) (Data)
+
+#define __REG(x) (x)
+#define __REGl(x) (x)
+#define __REGw(x) (x)
+#define __REGb(x) (x)
+#define __REG2(x, y) ((x) + (y))
+#endif
+
+#define Fld(Size, Shft) (((Size) << 16) + (Shft))
+
+#define FSize(Field) ((Field) >> 16)
+#define FShft(Field) ((Field) & 0x0000FFFF)
+#define FMsk(Field) (((UData(1) << FSize(Field)) - 1) << FShft(Field))
+#define FAlnMsk(Field) ((UData(1) << FSize(Field)) - 1)
+#define F1stBit(Field) (UData(1) << FShft(Field))
+
+#define FClrBit(Data, Bit) (Data = (Data & ~(Bit)))
+#define FClrFld(Data, Field) (Data = (Data & ~FMsk(Field)))
+
+#define FInsrt(Value, Field) \
+ (UData(Value) << FShft(Field))
+
+#define FExtr(Data, Field) \
+ ((UData(Data) >> FShft(Field)) & FAlnMsk(Field))
+
+#endif /* _ARCH_HARDWARE_H_ */
diff --git a/include/asm-arm/arch-s5pc1xx/i2c.h b/include/asm-arm/arch-s5pc1xx/i2c.h
new file mode 100644
index 0000000..6c7d3b6
--- /dev/null
+++ b/include/asm-arm/arch-s5pc1xx/i2c.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang(a)samsung.com>
+ * Kyungnin Park <kyungmin.park(a)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__
+struct s5pc1xx_i2c {
+ unsigned long IICCON;
+ unsigned long IICSTAT;
+ unsigned long IICADD;
+ unsigned long IICDS;
+ unsigned long IICLC;
+};
+#endif
+
+#endif
diff --git a/include/asm-arm/arch-s5pc1xx/interrupt.h b/include/asm-arm/arch-s5pc1xx/interrupt.h
new file mode 100644
index 0000000..a3c8680
--- /dev/null
+++ b/include/asm-arm/arch-s5pc1xx/interrupt.h
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang(a)samsung.com>
+ * Heungjun Kim <riverful.kim(a)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_INTERRUPT_H_
+#define __ASM_ARM_ARCH_INTERRUPT_H_
+
+/* Vector Interrupt Offset */
+#define VIC_IRQSTATUS_OFFSET 0x0
+#define VIC_FIQSTATUS_OFFSET 0x4
+#define VIC_RAWINTR_OFFSET 0x8
+#define VIC_INTSELECT_OFFSET 0xc
+#define VIC_INTENABLE_OFFSET 0x10
+#define VIC_INTENCLEAR_OFFSET 0x14
+#define VIC_SOFTINT_OFFSET 0x18
+#define VIC_SOFTINTCLEAR_OFFSET 0x1c
+#define VIC_PROTECTION_OFFSET 0x20
+#define VIC_SWPRIORITYMASK_OFFSET 0x24
+#define VIC_PRIORITYDAISY_OFFSET 0x28
+#define VIC_INTADDRESS_OFFSET 0xf00
+
+#endif
diff --git a/include/asm-arm/arch-s5pc1xx/mem.h b/include/asm-arm/arch-s5pc1xx/mem.h
new file mode 100644
index 0000000..4b06aaf
--- /dev/null
+++ b/include/asm-arm/arch-s5pc1xx/mem.h
@@ -0,0 +1,58 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang(a)samsung.com>
+ * Heungjun Kim <riverful.kim(a)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_
+
+/*
+ * SROMC Controller
+ */
+/* DRAM Memory Controller */
+#define S5PC100_DMC_BASE 0xE6000000
+#define S5PC110_DMC0_BASE 0xF0000000
+#define S5PC110_DMC1_BASE 0xF1400000
+
+/* DMC offset */
+#define CONCONTROL_OFFSET 0x00
+#define MEMCONTROL_OFFSET 0x04
+#define MEMCONFIG0_OFFSET 0x08
+#define MEMCONFIG1_OFFSET 0x0c
+#define DIRECTCMD_OFFSET 0x10
+#define PRECHCONFIG_OFFSET 0x14
+#define PHYCONTROL0_OFFSET 0x18
+#define PHYCONTROL1_OFFSET 0x1c
+#define PHYCONTROL2_OFFSET 0x20
+#define PWRDNCONFIG_OFFSET 0x28
+#define TIMINGAREF_OFFSET 0x30
+#define TIMINGROW_OFFSET 0x34
+#define TIMINGDATA_OFFSET 0x38
+#define TIMINGPOWER_OFFSET 0x3c
+#define PHYSTATUS0_OFFSET 0x40
+#define PHYSTATUS1_OFFSET 0x44
+#define CHIP0STATUS_OFFSET 0x48
+#define CHIP1STATUS_OFFSET 0x4c
+#define AREFSTATUS_OFFSET 0x50
+#define MRSTATUS_OFFSET 0x54
+#define PHYTEST0_OFFSET 0x58
+#define PHYTEST1_OFFSET 0x5c
+
+#endif
diff --git a/include/asm-arm/arch-s5pc1xx/power.h b/include/asm-arm/arch-s5pc1xx/power.h
new file mode 100644
index 0000000..57e2a2b
--- /dev/null
+++ b/include/asm-arm/arch-s5pc1xx/power.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2009 Samsung Electronics
+ * Kyungmin Park <kyungmin.park(a)samsung.com>
+ * Minkyu Kang <mk7.kang(a)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 S5PC100_OTHERS 0xE0108200
+#define S5PC100_RST_STAT 0xE0108300
+#define S5PC100_SLEEP_WAKEUP (1 << 3)
+#define S5PC100_WAKEUP_STAT 0xE0108304
+#define S5PC100_INFORM0 0xE0108400
+
+#define S5PC110_RST_STAT 0xE010A000
+#define S5PC110_SLEEP_WAKEUP (1 << 3)
+#define S5PC110_WAKEUP_STAT 0xE010C200
+#define S5PC110_OTHERS 0xE010E000
+#define S5PC110_USB_PHY_CON 0xE010E80C
+#define S5PC110_INFORM0 0xE010F000
+
+#endif
diff --git a/include/asm-arm/arch-s5pc1xx/pwm.h b/include/asm-arm/arch-s5pc1xx/pwm.h
new file mode 100644
index 0000000..85c63d7
--- /dev/null
+++ b/include/asm-arm/arch-s5pc1xx/pwm.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Kyungmin Park <kyungmin.park(a)samsung.com>
+ * Minkyu Kang <mk7.kang(a)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
+ */
+#define S5PC100_PWMTIMER_BASE 0xEA000000
+#define S5PC110_PWMTIMER_BASE 0xE2500000
+
+/* PWM timer addressing */
+#define S5PC100_TIMER_BASE S5PC100_PWMTIMER_BASE
+#define S5PC110_TIMER_BASE S5PC110_PWMTIMER_BASE
+
+/* Interval mode(Auto Reload) of PWM Timer 4 */
+#define S5PC1XX_TCON4_AUTO_RELOAD (1 << 22)
+/* Update TCNTB4 */
+#define S5PC1XX_TCON4_UPDATE (1 << 21)
+/* start bit of PWM Timer 4 */
+#define S5PC1XX_TCON4_START (1 << 20)
+
+#ifndef __ASSEMBLY__
+struct s5pc1xx_timer {
+ unsigned long TCFG0;
+ unsigned long TCFG1;
+ unsigned long TCON;
+ unsigned long TCNTB0;
+ unsigned long TCMPB0;
+ unsigned long TCNTO0;
+ unsigned long TCNTB1;
+ unsigned long TCMPB1;
+ unsigned long TCNTO1;
+ unsigned long TCNTB2;
+ unsigned long TCMPB2;
+ unsigned long TCNTO2;
+ unsigned long TCNTB3;
+ unsigned long res1;
+ unsigned long TCNTO3;
+ unsigned long TCNTB4;
+ unsigned long TCNTO4;
+ unsigned long TINTCSTAT;
+};
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/include/asm-arm/arch-s5pc1xx/uart.h b/include/asm-arm/arch-s5pc1xx/uart.h
new file mode 100644
index 0000000..1a2ca41
--- /dev/null
+++ b/include/asm-arm/arch-s5pc1xx/uart.h
@@ -0,0 +1,53 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang(a)samsung.com>
+ * Heungjun Kim <riverful.kim(a)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_
+
+/*
+ * UART
+ */
+/* uart base address */
+#define S5PC100_PA_UART 0xEC000000
+#define S5PC110_PA_UART 0xE2900000
+
+#ifndef __ASSEMBLY__
+struct s5pc1xx_uart {
+ unsigned long ULCON;
+ unsigned long UCON;
+ unsigned long UFCON;
+ unsigned long UMCON;
+ unsigned long UTRSTAT;
+ unsigned long UERSTAT;
+ unsigned long UFSTAT;
+ unsigned long UMSTAT;
+ unsigned char UTXH;
+ unsigned char res1[3];
+ unsigned char URXH;
+ unsigned char res2[3];
+ unsigned long UBRDIV;
+ unsigned short UDIVSLOT;
+ unsigned char res3[2];
+};
+#endif /* __ASSEMBLY__ */
+
+#endif
--
1.5.4.3
4
8

09 Oct '09
NULL is an absolute value and should not be relocated.
After this correction code like:
void weak_fun(void) __attribute__((weak));
printf("weak_fun:%p\n", weak_fun);
will still print null after relocation.
Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund(a)transmode.se>
---
v2 - add ppc4xx
v3 - add 74xx_7xx
cpu/74xx_7xx/start.S | 6 ++++--
cpu/mpc512x/start.S | 6 ++++--
cpu/mpc5xx/start.S | 6 ++++--
cpu/mpc5xxx/start.S | 6 ++++--
cpu/mpc8220/start.S | 6 ++++--
cpu/mpc824x/start.S | 6 ++++--
cpu/mpc8260/start.S | 6 ++++--
cpu/mpc83xx/start.S | 6 ++++--
cpu/mpc85xx/start.S | 6 ++++--
cpu/mpc86xx/start.S | 6 ++++--
cpu/mpc8xx/start.S | 6 ++++--
cpu/ppc4xx/start.S | 6 ++++--
12 files changed, 48 insertions(+), 24 deletions(-)
diff --git a/cpu/74xx_7xx/start.S b/cpu/74xx_7xx/start.S
index 792cd30..23381a3 100644
--- a/cpu/74xx_7xx/start.S
+++ b/cpu/74xx_7xx/start.S
@@ -716,15 +716,17 @@ in_ram:
sub r11,r3,r11
addi r3,r3,-4
1: lwzu r0,4(r3)
+ cmpwi r0,0
+ beq- 2f
add r0,r0,r11
stw r0,0(r3)
- bdnz 1b
+2: bdnz 1b
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
-2: li r0,__fixup_entries@sectoff@l
+ li r0,__fixup_entries@sectoff@l
lwz r3,GOT(_FIXUP_TABLE_)
cmpwi r0,0
mtctr r0
diff --git a/cpu/mpc512x/start.S b/cpu/mpc512x/start.S
index 360682d..a00e045 100644
--- a/cpu/mpc512x/start.S
+++ b/cpu/mpc512x/start.S
@@ -609,15 +609,17 @@ in_ram:
sub r11,r3,r11
addi r3,r3,-4
1: lwzu r0,4(r3)
+ cmpwi r0,0
+ beq- 2f
add r0,r0,r11
stw r0,0(r3)
- bdnz 1b
+2: bdnz 1b
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
-2: li r0,__fixup_entries@sectoff@l
+ li r0,__fixup_entries@sectoff@l
lwz r3,GOT(_FIXUP_TABLE_)
cmpwi r0,0
mtctr r0
diff --git a/cpu/mpc5xx/start.S b/cpu/mpc5xx/start.S
index 106935c..85ea7a8 100644
--- a/cpu/mpc5xx/start.S
+++ b/cpu/mpc5xx/start.S
@@ -458,15 +458,17 @@ in_ram:
sub r11,r3,r11
addi r3,r3,-4
1: lwzu r0,4(r3)
+ cmpwi r0,0
+ beq- 2f
add r0,r0,r11
stw r0,0(r3)
- bdnz 1b
+2: bdnz 1b
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
-2: li r0,__fixup_entries@sectoff@l
+ li r0,__fixup_entries@sectoff@l
lwz r3,GOT(_FIXUP_TABLE_)
cmpwi r0,0
mtctr r0
diff --git a/cpu/mpc5xxx/start.S b/cpu/mpc5xxx/start.S
index 6b1162a..eb42939 100644
--- a/cpu/mpc5xxx/start.S
+++ b/cpu/mpc5xxx/start.S
@@ -684,15 +684,17 @@ in_ram:
sub r11,r3,r11
addi r3,r3,-4
1: lwzu r0,4(r3)
+ cmpwi r0,0
+ beq- 2f
add r0,r0,r11
stw r0,0(r3)
- bdnz 1b
+2: bdnz 1b
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
-2: li r0,__fixup_entries@sectoff@l
+ li r0,__fixup_entries@sectoff@l
lwz r3,GOT(_FIXUP_TABLE_)
cmpwi r0,0
mtctr r0
diff --git a/cpu/mpc8220/start.S b/cpu/mpc8220/start.S
index 3abc619..af9472d 100644
--- a/cpu/mpc8220/start.S
+++ b/cpu/mpc8220/start.S
@@ -649,15 +649,17 @@ in_ram:
sub r11,r3,r11
addi r3,r3,-4
1: lwzu r0,4(r3)
+ cmpwi r0,0
+ beq- 2f
add r0,r0,r11
stw r0,0(r3)
- bdnz 1b
+2: bdnz 1b
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
-2: li r0,__fixup_entries@sectoff@l
+ li r0,__fixup_entries@sectoff@l
lwz r3,GOT(_FIXUP_TABLE_)
cmpwi r0,0
mtctr r0
diff --git a/cpu/mpc824x/start.S b/cpu/mpc824x/start.S
index 39325cd..750457b 100644
--- a/cpu/mpc824x/start.S
+++ b/cpu/mpc824x/start.S
@@ -589,15 +589,17 @@ in_ram:
sub r11,r3,r11
addi r3,r3,-4
1: lwzu r0,4(r3)
+ cmpwi r0,0
+ beq- 2f
add r0,r0,r11
stw r0,0(r3)
- bdnz 1b
+2: bdnz 1b
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
-2: li r0,__fixup_entries@sectoff@l
+ li r0,__fixup_entries@sectoff@l
lwz r3,GOT(_FIXUP_TABLE_)
cmpwi r0,0
mtctr r0
diff --git a/cpu/mpc8260/start.S b/cpu/mpc8260/start.S
index 379f2fb..edb95e6 100644
--- a/cpu/mpc8260/start.S
+++ b/cpu/mpc8260/start.S
@@ -909,15 +909,17 @@ in_ram:
sub r11,r3,r11
addi r3,r3,-4
1: lwzu r0,4(r3)
+ cmpwi r0,0
+ beq- 2f
add r0,r0,r11
stw r0,0(r3)
- bdnz 1b
+2: bdnz 1b
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
-2: li r0,__fixup_entries@sectoff@l
+ li r0,__fixup_entries@sectoff@l
lwz r3,GOT(_FIXUP_TABLE_)
cmpwi r0,0
mtctr r0
diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S
index 26e3106..ee4b862 100644
--- a/cpu/mpc83xx/start.S
+++ b/cpu/mpc83xx/start.S
@@ -957,16 +957,18 @@ in_ram:
sub r11,r3,r11
addi r3,r3,-4
1: lwzu r0,4(r3)
+ cmpwi r0,0
+ beq- 2f
add r0,r0,r11
stw r0,0(r3)
- bdnz 1b
+2: bdnz 1b
#ifndef CONFIG_NAND_SPL
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
-2: li r0,__fixup_entries@sectoff@l
+ li r0,__fixup_entries@sectoff@l
lwz r3,GOT(_FIXUP_TABLE_)
cmpwi r0,0
mtctr r0
diff --git a/cpu/mpc85xx/start.S b/cpu/mpc85xx/start.S
index 4f7236f..d56003b 100644
--- a/cpu/mpc85xx/start.S
+++ b/cpu/mpc85xx/start.S
@@ -932,15 +932,17 @@ in_ram:
sub r11,r3,r11
addi r3,r3,-4
1: lwzu r0,4(r3)
+ cmpwi r0,0
+ beq- 2f
add r0,r0,r11
stw r0,0(r3)
- bdnz 1b
+2: bdnz 1b
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
-2: li r0,__fixup_entries@sectoff@l
+ li r0,__fixup_entries@sectoff@l
lwz r3,GOT(_FIXUP_TABLE_)
cmpwi r0,0
mtctr r0
diff --git a/cpu/mpc86xx/start.S b/cpu/mpc86xx/start.S
index 63cc8db..e65f1c0 100644
--- a/cpu/mpc86xx/start.S
+++ b/cpu/mpc86xx/start.S
@@ -733,15 +733,17 @@ in_ram:
sub r11,r3,r11
addi r3,r3,-4
1: lwzu r0,4(r3)
+ cmpwi r0,0
+ beq- 2f
add r0,r0,r11
stw r0,0(r3)
- bdnz 1b
+2: bdnz 1b
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
-2: li r0,__fixup_entries@sectoff@l
+ li r0,__fixup_entries@sectoff@l
lwz r3,GOT(_FIXUP_TABLE_)
cmpwi r0,0
mtctr r0
diff --git a/cpu/mpc8xx/start.S b/cpu/mpc8xx/start.S
index 8864c37..e84326e 100644
--- a/cpu/mpc8xx/start.S
+++ b/cpu/mpc8xx/start.S
@@ -589,15 +589,17 @@ in_ram:
sub r11,r3,r11
addi r3,r3,-4
1: lwzu r0,4(r3)
+ cmpwi r0,0
+ beq- 2f
add r0,r0,r11
stw r0,0(r3)
- bdnz 1b
+2: bdnz 1b
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
-2: li r0,__fixup_entries@sectoff@l
+ li r0,__fixup_entries@sectoff@l
lwz r3,GOT(_FIXUP_TABLE_)
cmpwi r0,0
mtctr r0
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index f2b8908..c3cf2ba 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -1568,15 +1568,17 @@ in_ram:
sub r11,r3,r11
addi r3,r3,-4
1: lwzu r0,4(r3)
+ cmpwi r0,0
+ beq- 2f
add r0,r0,r11
stw r0,0(r3)
- bdnz 1b
+2: bdnz 1b
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
-2: li r0,__fixup_entries@sectoff@l
+ li r0,__fixup_entries@sectoff@l
lwz r3,GOT(_FIXUP_TABLE_)
cmpwi r0,0
mtctr r0
--
1.6.4.4
4
6
I've added 32-bit lcd to the Nomadik (not submitted yet), and I found
the scroll to be very slow, as the screen is big.
Instead of activating the "if 0" stanza for 32-bit scroll in lcd.c,
I'd better have a faster memcpy/memset globally. So this patch set
adds ulong-wide memcpy and memset, then removes the "#if 0" part in the
scroll function. For me scrolling is 4 times faster on a 32 bit system.
V2: I incorporated most of the comments, but I didn't change the for
loops to help the compiler optimizing it, since nowadays gcc is
already doing the loops his own way irrespective of what i write.
Similarly, I'm not interested in "4 bytes at a time, then 1 at a time"
as it's quite a corner case. If such optimizations are really useful,
then we'd better have hand-crafted assembly for each arch, possibly
lifted from glibc.
Alessandro Rubini (3):
memcpy: copy one word at a time if possible
memset: fill one word at a time if possible
lcd: remove '#if 0' 32-bit scroll, now memcpy does it
common/lcd.c | 21 ---------------------
lib_generic/string.c | 34 +++++++++++++++++++++++++++++-----
2 files changed, 29 insertions(+), 26 deletions(-)
3
5