* [PATCH 2/4] Fine split S3C arch dependencies from generic code
2012-05-03 13:14 [PATCH 0/4] Support Samsung S5PV210 CPU Alexey Galakhov
2012-05-03 13:14 ` [PATCH 1/4] Support most Samsung SoCs in S3C serial driver Alexey Galakhov
@ 2012-05-03 13:14 ` Alexey Galakhov
2012-05-03 17:41 ` Juergen Beisert
2012-05-03 13:14 ` [PATCH 3/4] Minimal S5PV210 + Tiny210 support (2nd stage only) Alexey Galakhov
2012-05-03 13:14 ` [PATCH 4/4] S5PV210 iROM magic boot code Alexey Galakhov
3 siblings, 1 reply; 19+ messages in thread
From: Alexey Galakhov @ 2012-05-03 13:14 UTC (permalink / raw)
To: barebox; +Cc: Alexey Galakhov
Signed-off-by: Alexey Galakhov <agalakhov@gmail.com>
---
arch/arm/boards/a9m2410/a9m2410.c | 12 +-
arch/arm/boards/a9m2410/config.h | 2 +-
arch/arm/boards/a9m2410/lowlevel_init.S | 2 +-
arch/arm/boards/a9m2440/a9m2410dev.c | 2 +-
arch/arm/boards/a9m2440/a9m2440.c | 12 +-
arch/arm/boards/a9m2440/config.h | 2 +-
arch/arm/boards/a9m2440/lowlevel_init.S | 4 +-
arch/arm/boards/mini2440/config.h | 2 +-
arch/arm/boards/mini2440/lowlevel_init.S | 2 +-
arch/arm/boards/mini2440/mini2440.c | 12 +-
arch/arm/configs/a9m2410_defconfig | 2 +-
arch/arm/configs/a9m2440_defconfig | 4 +-
arch/arm/configs/mini2440_defconfig | 2 +-
arch/arm/mach-samsung/Kconfig | 30 +-
arch/arm/mach-samsung/Makefile | 5 +-
arch/arm/mach-samsung/clocks-s3c24x0.c | 157 +++++
arch/arm/mach-samsung/generic.c | 112 ----
arch/arm/mach-samsung/gpio-s3c24x0.c | 2 +-
.../arm/mach-samsung/include/mach/clocks-s3c24x0.h | 24 +
arch/arm/mach-samsung/include/mach/gpio-s3c24x0.h | 77 +++
arch/arm/mach-samsung/include/mach/iomap-s3c24x0.h | 69 ++
arch/arm/mach-samsung/include/mach/s3c-clocks.h | 22 +-
arch/arm/mach-samsung/include/mach/s3c-generic.h | 4 +-
arch/arm/mach-samsung/include/mach/s3c-iomap.h | 53 +-
arch/arm/mach-samsung/include/mach/s3c-nand.h | 54 ++
arch/arm/mach-samsung/include/mach/s3c24xx-gpio.h | 77 ---
arch/arm/mach-samsung/include/mach/s3c24xx-nand.h | 54 --
arch/arm/mach-samsung/lowlevel-init.S | 317 ----------
arch/arm/mach-samsung/lowlevel-s3c24x0.S | 317 ++++++++++
arch/arm/mach-samsung/mem-s3c24x0.c | 143 +++++
arch/arm/mach-samsung/s3c24xx-clocks.c | 157 -----
drivers/mtd/nand/Kconfig | 4 +-
drivers/mtd/nand/Makefile | 2 +-
drivers/mtd/nand/nand_s3c.c | 665 ++++++++++++++++++++
drivers/mtd/nand/nand_s3c24xx.c | 665 --------------------
drivers/serial/Kconfig | 2 +-
36 files changed, 1576 insertions(+), 1496 deletions(-)
create mode 100644 arch/arm/mach-samsung/clocks-s3c24x0.c
create mode 100644 arch/arm/mach-samsung/include/mach/clocks-s3c24x0.h
create mode 100644 arch/arm/mach-samsung/include/mach/gpio-s3c24x0.h
create mode 100644 arch/arm/mach-samsung/include/mach/iomap-s3c24x0.h
create mode 100644 arch/arm/mach-samsung/include/mach/s3c-nand.h
delete mode 100644 arch/arm/mach-samsung/include/mach/s3c24xx-gpio.h
delete mode 100644 arch/arm/mach-samsung/include/mach/s3c24xx-nand.h
delete mode 100644 arch/arm/mach-samsung/lowlevel-init.S
create mode 100644 arch/arm/mach-samsung/lowlevel-s3c24x0.S
create mode 100644 arch/arm/mach-samsung/mem-s3c24x0.c
delete mode 100644 arch/arm/mach-samsung/s3c24xx-clocks.c
create mode 100644 drivers/mtd/nand/nand_s3c.c
delete mode 100644 drivers/mtd/nand/nand_s3c24xx.c
diff --git a/arch/arm/boards/a9m2410/a9m2410.c b/arch/arm/boards/a9m2410/a9m2410.c
index adeaacc..19bf66a 100644
--- a/arch/arm/boards/a9m2410/a9m2410.c
+++ b/arch/arm/boards/a9m2410/a9m2410.c
@@ -33,13 +33,13 @@
#include <nand.h>
#include <io.h>
#include <mach/s3c-iomap.h>
-#include <mach/s3c24xx-nand.h>
+#include <mach/s3c-nand.h>
#include <mach/s3c-generic.h>
#include <mach/s3c-busctl.h>
-#include <mach/s3c24xx-gpio.h>
+#include <mach/gpio-s3c24x0.h>
// {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, 0},
-static struct s3c24x0_nand_platform_data nand_info = {
+static struct s3c_nand_platform_data nand_info = {
.nand_timing = CALC_NFCONF_TIMING(A9M2410_TACLS, A9M2410_TWRPH0, A9M2410_TWRPH1)
};
@@ -51,7 +51,7 @@ static int a9m2410_mem_init(void)
* Note: On this card the second SDRAM page is not used
*/
s3c24xx_disable_second_sdram_bank();
- size = s3c24xx_get_memory_size();
+ size = s3c_get_memory_size();
/* ---------- configure the GPIOs ------------- */
writel(0x007FFFFF, S3C_GPACON);
@@ -136,10 +136,10 @@ static int a9m2410_devices_init(void)
device_initcall(a9m2410_devices_init);
-#ifdef CONFIG_S3C24XX_NAND_BOOT
+#ifdef CONFIG_S3C_NAND_BOOT
void __bare_init nand_boot(void)
{
- s3c24x0_nand_load_image((void *)TEXT_BASE, 256 * 1024, 0);
+ s3c_nand_load_image((void *)TEXT_BASE, 256 * 1024, 0);
}
#endif
diff --git a/arch/arm/boards/a9m2410/config.h b/arch/arm/boards/a9m2410/config.h
index 87b05fc..4b8a9a2 100644
--- a/arch/arm/boards/a9m2410/config.h
+++ b/arch/arm/boards/a9m2410/config.h
@@ -115,7 +115,7 @@
#define A9M2410_TWRPH1 1
/* needed in the generic NAND boot code only */
-#ifdef CONFIG_S3C24XX_NAND_BOOT
+#ifdef CONFIG_S3C_NAND_BOOT
# define BOARD_DEFAULT_NAND_TIMING CALC_NFCONF_TIMING(A9M2410_TACLS, A9M2410_TWRPH0, A9M2410_TWRPH1)
#endif
diff --git a/arch/arm/boards/a9m2410/lowlevel_init.S b/arch/arm/boards/a9m2410/lowlevel_init.S
index a106d53..0463b26 100644
--- a/arch/arm/boards/a9m2410/lowlevel_init.S
+++ b/arch/arm/boards/a9m2410/lowlevel_init.S
@@ -28,7 +28,7 @@ board_init_lowlevel:
bl s3c24x0_sdram_init
-#ifdef CONFIG_S3C24XX_NAND_BOOT
+#ifdef CONFIG_S3C_NAND_BOOT
mov lr, r10 /* restore the link register */
/* up to here we are running from the internal SRAM area */
b s3c24x0_nand_boot /* does return directly to our caller into SDRAM */
diff --git a/arch/arm/boards/a9m2440/a9m2410dev.c b/arch/arm/boards/a9m2440/a9m2410dev.c
index bedb0f7..f23fc5d 100644
--- a/arch/arm/boards/a9m2440/a9m2410dev.c
+++ b/arch/arm/boards/a9m2440/a9m2410dev.c
@@ -30,7 +30,7 @@
#include <io.h>
#include <mach/s3c-iomap.h>
#include <mach/s3c-busctl.h>
-#include <mach/s3c24xx-gpio.h>
+#include <mach/gpio-s3c24x0.h>
/**
* Initialize the CPU to be able to work with the a9m2410dev evaluation board
diff --git a/arch/arm/boards/a9m2440/a9m2440.c b/arch/arm/boards/a9m2440/a9m2440.c
index 6c6ccdb..94618ae 100644
--- a/arch/arm/boards/a9m2440/a9m2440.c
+++ b/arch/arm/boards/a9m2440/a9m2440.c
@@ -33,14 +33,14 @@
#include <nand.h>
#include <io.h>
#include <mach/s3c-iomap.h>
-#include <mach/s3c24xx-nand.h>
+#include <mach/s3c-nand.h>
#include <mach/s3c-generic.h>
#include <mach/s3c-busctl.h>
-#include <mach/s3c24xx-gpio.h>
+#include <mach/gpio-s3c24x0.h>
#include "baseboards.h"
-static struct s3c24x0_nand_platform_data nand_info = {
+static struct s3c_nand_platform_data nand_info = {
.nand_timing = CALC_NFCONF_TIMING(A9M2440_TACLS, A9M2440_TWRPH0, A9M2440_TWRPH1)
};
@@ -99,7 +99,7 @@ static int a9m2440_mem_init(void)
break;
}
- arm_add_mem_device("ram0", S3C_SDRAM_BASE, s3c24xx_get_memory_size());
+ arm_add_mem_device("ram0", S3C_SDRAM_BASE, s3c_get_memory_size());
return 0;
}
@@ -155,10 +155,10 @@ static int a9m2440_devices_init(void)
device_initcall(a9m2440_devices_init);
-#ifdef CONFIG_S3C24XX_NAND_BOOT
+#ifdef CONFIG_S3C_NAND_BOOT
void __bare_init nand_boot(void)
{
- s3c24x0_nand_load_image((void *)TEXT_BASE, 256 * 1024, 0);
+ s3c_nand_load_image((void *)TEXT_BASE, 256 * 1024, 0);
}
#endif
diff --git a/arch/arm/boards/a9m2440/config.h b/arch/arm/boards/a9m2440/config.h
index 43cb6ab..09ad949 100644
--- a/arch/arm/boards/a9m2440/config.h
+++ b/arch/arm/boards/a9m2440/config.h
@@ -66,7 +66,7 @@
#define A9M2440_TWRPH1 1
/* needed in the generic NAND boot code only */
-#ifdef CONFIG_S3C24XX_NAND_BOOT
+#ifdef CONFIG_S3C_NAND_BOOT
# define BOARD_DEFAULT_NAND_TIMING CALC_NFCONF_TIMING(A9M2440_TACLS, A9M2440_TWRPH0, A9M2440_TWRPH1)
#endif
diff --git a/arch/arm/boards/a9m2440/lowlevel_init.S b/arch/arm/boards/a9m2440/lowlevel_init.S
index e915a16..f6522f4 100644
--- a/arch/arm/boards/a9m2440/lowlevel_init.S
+++ b/arch/arm/boards/a9m2440/lowlevel_init.S
@@ -4,7 +4,7 @@
#include <config.h>
#include <mach/s3c-iomap.h>
-#include <mach/s3c24xx-gpio.h>
+#include <mach/gpio-s3c24x0.h>
.section ".text_bare_init.board_init_lowlevel","ax"
@@ -232,7 +232,7 @@ board_init_lowlevel:
bl sdram_init
-#ifdef CONFIG_S3C24XX_NAND_BOOT
+#ifdef CONFIG_S3C_NAND_BOOT
mov lr, r10 /* restore the link register */
/* up to here we are running from the internal SRAM area */
b s3c24x0_nand_boot /* does return directly to our caller into SDRAM */
diff --git a/arch/arm/boards/mini2440/config.h b/arch/arm/boards/mini2440/config.h
index 8d36193..674d974 100644
--- a/arch/arm/boards/mini2440/config.h
+++ b/arch/arm/boards/mini2440/config.h
@@ -66,7 +66,7 @@
#define MINI2440_TWRPH1 1
/* needed in the generic NAND boot code only */
-#ifdef CONFIG_S3C24XX_NAND_BOOT
+#ifdef CONFIG_S3C_NAND_BOOT
# define BOARD_DEFAULT_NAND_TIMING \
CALC_NFCONF_TIMING(MINI2440_TACLS, MINI2440_TWRPH0, MINI2440_TWRPH1)
#endif
diff --git a/arch/arm/boards/mini2440/lowlevel_init.S b/arch/arm/boards/mini2440/lowlevel_init.S
index 1c8860a..827cf00 100644
--- a/arch/arm/boards/mini2440/lowlevel_init.S
+++ b/arch/arm/boards/mini2440/lowlevel_init.S
@@ -30,7 +30,7 @@ board_init_lowlevel:
bl s3c24x0_sdram_init
-#ifdef CONFIG_S3C24XX_NAND_BOOT
+#ifdef CONFIG_S3C_NAND_BOOT
mov lr, r10 /* restore the link register */
/* up to here we are running from the internal SRAM area */
b s3c24x0_nand_boot /* does return directly to our caller into SDRAM */
diff --git a/arch/arm/boards/mini2440/mini2440.c b/arch/arm/boards/mini2440/mini2440.c
index 97e56db..1bc60b0 100644
--- a/arch/arm/boards/mini2440/mini2440.c
+++ b/arch/arm/boards/mini2440/mini2440.c
@@ -39,14 +39,14 @@
#include <io.h>
#include <mach/gpio.h>
#include <mach/s3c-iomap.h>
-#include <mach/s3c24xx-nand.h>
+#include <mach/s3c-nand.h>
#include <mach/s3c-generic.h>
#include <mach/s3c-mci.h>
#include <mach/s3c24xx-fb.h>
#include <mach/s3c-busctl.h>
-#include <mach/s3c24xx-gpio.h>
+#include <mach/gpio-s3c24x0.h>
-static struct s3c24x0_nand_platform_data nand_info = {
+static struct s3c_nand_platform_data nand_info = {
.nand_timing = CALC_NFCONF_TIMING(MINI2440_TACLS, MINI2440_TWRPH0,
MINI2440_TWRPH1),
.flash_bbt = 1, /* same as the kernel */
@@ -268,7 +268,7 @@ static const unsigned pin_usage[] = {
static int mini2440_mem_init(void)
{
- arm_add_mem_device("ram0", S3C_SDRAM_BASE, s3c24xx_get_memory_size());
+ arm_add_mem_device("ram0", S3C_SDRAM_BASE, s3c_get_memory_size());
return 0;
}
@@ -326,10 +326,10 @@ static int mini2440_devices_init(void)
device_initcall(mini2440_devices_init);
-#ifdef CONFIG_S3C24XX_NAND_BOOT
+#ifdef CONFIG_S3C_NAND_BOOT
void __bare_init nand_boot(void)
{
- s3c24x0_nand_load_image((void *)TEXT_BASE, 256 * 1024, 0);
+ s3c_nand_load_image((void *)TEXT_BASE, 256 * 1024, 0);
}
#endif
diff --git a/arch/arm/configs/a9m2410_defconfig b/arch/arm/configs/a9m2410_defconfig
index 57e73c7..1955023 100644
--- a/arch/arm/configs/a9m2410_defconfig
+++ b/arch/arm/configs/a9m2410_defconfig
@@ -1,5 +1,5 @@
CONFIG_ARCH_S3C24xx=y
-CONFIG_S3C24XX_NAND_BOOT=y
+CONFIG_S3C_NAND_BOOT=y
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
CONFIG_BROKEN=y
CONFIG_EXPERIMENTAL=y
diff --git a/arch/arm/configs/a9m2440_defconfig b/arch/arm/configs/a9m2440_defconfig
index ae7f523..ebdf64f 100644
--- a/arch/arm/configs/a9m2440_defconfig
+++ b/arch/arm/configs/a9m2440_defconfig
@@ -1,7 +1,7 @@
CONFIG_ARCH_S3C24xx=y
CONFIG_MACH_A9M2440=y
-CONFIG_S3C24XX_SDRAM_INIT=y
-CONFIG_S3C24XX_NAND_BOOT=y
+CONFIG_S3C_SDRAM_INIT=y
+CONFIG_S3C_NAND_BOOT=y
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
CONFIG_BROKEN=y
CONFIG_EXPERIMENTAL=y
diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig
index 9b35dd5..efe76e4 100644
--- a/arch/arm/configs/mini2440_defconfig
+++ b/arch/arm/configs/mini2440_defconfig
@@ -1,7 +1,7 @@
CONFIG_ARCH_S3C24xx=y
CONFIG_MACH_MINI2440=y
CONFIG_MINI2440_VIDEO_N35=y
-CONFIG_S3C24XX_NAND_BOOT=y
+CONFIG_S3C_NAND_BOOT=y
CONFIG_AEABI=y
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
CONFIG_TEXT_BASE=0x33e00000
diff --git a/arch/arm/mach-samsung/Kconfig b/arch/arm/mach-samsung/Kconfig
index bc283dc..4d5f7c5 100644
--- a/arch/arm/mach-samsung/Kconfig
+++ b/arch/arm/mach-samsung/Kconfig
@@ -30,8 +30,8 @@ config MACH_A9M2410
bool "Digi A9M2410"
select CPU_S3C2410
select MACH_HAS_LOWLEVEL_INIT
- select S3C24XX_PLL_INIT
- select S3C24XX_SDRAM_INIT
+ select S3C_PLL_INIT
+ select S3C_SDRAM_INIT
help
Say Y here if you are using Digi's Connect Core 9M equipped
with a Samsung S3C2410 Processor
@@ -40,7 +40,7 @@ config MACH_A9M2440
bool "Digi A9M2440"
select CPU_S3C2440
select MACH_HAS_LOWLEVEL_INIT
- select S3C24XX_PLL_INIT
+ select S3C_PLL_INIT
help
Say Y here if you are using Digi's Connect Core 9M equipped
with a Samsung S3C2440 Processor
@@ -50,8 +50,8 @@ config MACH_MINI2440
select CPU_S3C2440
select MACH_HAS_LOWLEVEL_INIT
select MACH_DO_LOWLEVEL_INIT
- select S3C24XX_PLL_INIT
- select S3C24XX_SDRAM_INIT
+ select S3C_PLL_INIT
+ select S3C_SDRAM_INIT
select HAS_DM9000
help
Say Y here if you are using Mini 2440 dev board equipped
@@ -78,34 +78,36 @@ source arch/arm/boards/mini2440/Kconfig
endmenu
-menu "S3C24X0 Features "
+endif
+
+menu "S3C Features "
-config S3C24XX_LOW_LEVEL_INIT
+config S3C_LOWLEVEL_INIT
bool
-config S3C24XX_PLL_INIT
+config S3C_PLL_INIT
bool
prompt "Reconfigure PLL"
- select S3C24XX_LOW_LEVEL_INIT
+ select S3C_LOWLEVEL_INIT
help
This adds generic code to reconfigure the internal PLL very early
after reset.
-config S3C24XX_SDRAM_INIT
+config S3C_SDRAM_INIT
bool
prompt "Initialize SDRAM"
- select S3C24XX_LOW_LEVEL_INIT
+ select S3C_LOWLEVEL_INIT
help
This adds generic code to configure the SDRAM controller after reset.
The initialisation will be skipped if the code is already running
from SDRAM.
-config S3C24XX_NAND_BOOT
+config S3C_NAND_BOOT
bool
prompt "Booting from NAND"
select MTD
select NAND
- select NAND_S3C24XX
+ select NAND_S3C
help
Add generic support to boot from NAND flash. Image loading will be
skipped if the code is running from NOR or already from SDRAM.
@@ -113,5 +115,3 @@ config S3C24XX_NAND_BOOT
endmenu
endif
-
-endif
diff --git a/arch/arm/mach-samsung/Makefile b/arch/arm/mach-samsung/Makefile
index 2ba5c3f..8f032fb 100644
--- a/arch/arm/mach-samsung/Makefile
+++ b/arch/arm/mach-samsung/Makefile
@@ -1,3 +1,4 @@
obj-y += s3c-timer.o generic.o
-obj-$(CONFIG_ARCH_S3C24xx) += gpio-s3c24x0.o s3c24xx-clocks.o
-obj-$(CONFIG_S3C24XX_LOW_LEVEL_INIT) += lowlevel-init.o
+obj-lowlevel-$(CONFIG_ARCH_S3C24xx) += lowlevel-s3c24x0.o
+obj-$(CONFIG_ARCH_S3C24xx) += gpio-s3c24x0.o clocks-s3c24x0.o mem-s3c24x0.o
+obj-$(CONFIG_S3C_LOWLEVEL_INIT) += $(obj-lowlevel-y)
diff --git a/arch/arm/mach-samsung/clocks-s3c24x0.c b/arch/arm/mach-samsung/clocks-s3c24x0.c
new file mode 100644
index 0000000..38d8b75
--- /dev/null
+++ b/arch/arm/mach-samsung/clocks-s3c24x0.c
@@ -0,0 +1,157 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <io.h>
+#include <mach/s3c-iomap.h>
+#include <mach/s3c-generic.h>
+#include <mach/s3c-clocks.h>
+#include <mach/s3c-busctl.h>
+
+/**
+ * Calculate the current M-PLL clock.
+ * @return Current frequency in Hz
+ */
+uint32_t s3c_get_mpllclk(void)
+{
+ uint32_t m, p, s, reg_val;
+
+ reg_val = readl(S3C_MPLLCON);
+ m = ((reg_val & 0xFF000) >> 12) + 8;
+ p = ((reg_val & 0x003F0) >> 4) + 2;
+ s = reg_val & 0x3;
+#ifdef CONFIG_CPU_S3C2410
+ return (S3C24XX_CLOCK_REFERENCE * m) / (p << s);
+#endif
+#ifdef CONFIG_CPU_S3C2440
+ return 2 * m * (S3C24XX_CLOCK_REFERENCE / (p << s));
+#endif
+}
+
+/**
+ * Calculate the current U-PLL clock
+ * @return Current frequency in Hz
+ */
+uint32_t s3c_get_upllclk(void)
+{
+ uint32_t m, p, s, reg_val;
+
+ reg_val = readl(S3C_UPLLCON);
+ m = ((reg_val & 0xFF000) >> 12) + 8;
+ p = ((reg_val & 0x003F0) >> 4) + 2;
+ s = reg_val & 0x3;
+
+ return (S3C24XX_CLOCK_REFERENCE * m) / (p << s);
+}
+
+/**
+ * Calculate the FCLK frequency used for the ARM CPU core
+ * @return Current frequency in Hz
+ */
+uint32_t s3c_get_fclk(void)
+{
+ return s3c_get_mpllclk();
+}
+
+/**
+ * Calculate the HCLK frequency used for the AHB bus (CPU to main peripheral)
+ * @return Current frequency in Hz
+ */
+uint32_t s3c_get_hclk(void)
+{
+ uint32_t f_clk;
+
+ f_clk = s3c_get_fclk();
+#ifdef CONFIG_CPU_S3C2410
+ if (readl(S3C_CLKDIVN) & 0x02)
+ return f_clk >> 1;
+#endif
+#ifdef CONFIG_CPU_S3C2440
+ switch(readl(S3C_CLKDIVN) & 0x06) {
+ case 2:
+ return f_clk >> 1;
+ case 4:
+ return f_clk >> 2; /* TODO consider CAMDIVN */
+ case 6:
+ return f_clk / 3; /* TODO consider CAMDIVN */
+ }
+#endif
+ return f_clk;
+}
+
+/**
+ * Calculate the PCLK frequency used for the slower peripherals
+ * @return Current frequency in Hz
+ */
+uint32_t s3c_get_pclk(void)
+{
+ uint32_t p_clk;
+
+ p_clk = s3c_get_hclk();
+ if (readl(S3C_CLKDIVN) & 0x01)
+ return p_clk >> 1;
+ return p_clk;
+}
+
+/**
+ * Calculate the UCLK frequency used by the USB host device
+ * @return Current frequency in Hz
+ */
+uint32_t s3c24_get_uclk(void)
+{
+ return s3c_get_upllclk();
+}
+
+/**
+ * Return correct UART frequency based on the UCON register
+ */
+unsigned s3c_get_uart_clk(unsigned src)
+{
+ switch (src & 3) {
+ case 0:
+ case 2:
+ return s3c_get_pclk();
+ case 1:
+ return 0; /* TODO UEXTCLK */
+ case 3:
+ return 0; /* TODO FCLK/n */
+ }
+ return 0; /* not reached, to make compiler happy */
+}
+
+/**
+ * Show the user the current clock settings
+ */
+int s3c24xx_dump_clocks(void)
+{
+ printf("refclk: %7d kHz\n", S3C24XX_CLOCK_REFERENCE / 1000);
+ printf("mpll: %7d kHz\n", s3c_get_mpllclk() / 1000);
+ printf("upll: %7d kHz\n", s3c_get_upllclk() / 1000);
+ printf("fclk: %7d kHz\n", s3c_get_fclk() / 1000);
+ printf("hclk: %7d kHz\n", s3c_get_hclk() / 1000);
+ printf("pclk: %7d kHz\n", s3c_get_pclk() / 1000);
+ printf("SDRAM1: CL%d@%dMHz\n", ((readl(S3C_BANKCON6) & 0xc) >> 2) + 2,
+ s3c_get_hclk() / 1000000);
+ if ((readl(S3C_BANKCON7) & (0x3 << 15)) == (0x3 << 15))
+ printf("SDRAM2: CL%d@%dMHz\n",
+ ((readl(S3C_BANKCON7) & 0xc) >> 2) + 2,
+ s3c_get_hclk() / 1000000);
+ return 0;
+}
+
+late_initcall(s3c24xx_dump_clocks);
diff --git a/arch/arm/mach-samsung/generic.c b/arch/arm/mach-samsung/generic.c
index 7706be2..f919e24 100644
--- a/arch/arm/mach-samsung/generic.c
+++ b/arch/arm/mach-samsung/generic.c
@@ -25,65 +25,10 @@
#include <config.h>
#include <common.h>
#include <init.h>
-#include <clock.h>
#include <io.h>
-#include <sizes.h>
#include <mach/s3c-iomap.h>
#include <mach/s3c-generic.h>
-#include <mach/s3c-busctl.h>
-#include <mach/s3c24xx-gpio.h>
-/**
- * Calculate the amount of connected and available memory
- * @return Memory size in bytes
- */
-uint32_t s3c24xx_get_memory_size(void)
-{
- uint32_t reg, size;
-
- /*
- * detect the current memory size
- */
- reg = readl(S3C_BANKSIZE);
-
- switch (reg & 0x7) {
- case 0:
- size = SZ_32M;
- break;
- case 1:
- size = SZ_64M;
- break;
- case 2:
- size = SZ_128M;
- break;
- case 4:
- size = SZ_2M;
- break;
- case 5:
- size = SZ_4M;
- break;
- case 6:
- size = SZ_8M;
- break;
- default:
- size = SZ_16M;
- break;
- }
-
- /*
- * Is bank7 also configured for SDRAM usage?
- */
- if ((readl(S3C_BANKCON7) & (0x3 << 15)) == (0x3 << 15))
- size <<= 1; /* also count this bank */
-
- return size;
-}
-
-void s3c24xx_disable_second_sdram_bank(void)
-{
- writel(readl(S3C_BANKCON7) & ~(0x3 << 15), S3C_BANKCON7);
- writel(readl(S3C_MISCCR) | (1 << 18), S3C_MISCCR); /* disable its clock */
-}
#define S3C_WTCON (S3C_WATCHDOG_BASE)
#define S3C_WTDAT (S3C_WATCHDOG_BASE + 0x04)
@@ -105,60 +50,3 @@ void __noreturn reset_cpu(unsigned long addr)
;
}
EXPORT_SYMBOL(reset_cpu);
-
-/**
-
-@page dev_s3c24xx_arch Samsung's S3C24xx Platforms in barebox
-
-@section s3c24xx_boards Boards using S3C24xx Processors
-
-@li @subpage arch/arm/boards/a9m2410/a9m2410.c
-@li @subpage arch/arm/boards/a9m2440/a9m2440.c
-
-@section s3c24xx_arch Documentation for S3C24xx Architectures Files
-
-@li @subpage arch/arm/mach-s3c24xx/generic.c
-
-@section s3c24xx_mem_map SDRAM Memory Map
-
-SDRAM starts at address 0x3000.0000 up to the available amount of connected
-SDRAM memory. Physically this CPU can handle up to 256MiB (two areas with
-up to 128MiB each).
-
-@subsection s3c24xx_mem_generic_map Generic Map
-- 0x0000.0000 Start of the internal SRAM when booting from NAND flash memory or CS signal to a NOR flash memory.
-- 0x0800.0000 Start of I/O space.
-- 0x3000.0000 Start of SDRAM area.
- - 0x3000.0100 Start of the TAG list area.
- - 0x3000.8000 Start of the linux kernel (physical address).
-- 0x4000.0000 Start of internal SRAM, when booting from NOR flash memory
-- 0x4800.0000 Start of the internal I/O area
-
-@section s3c24xx_asm_arm include/asm-arm/arch-s3c24xx directory guidelines
-All S3C24xx common headers are located here.
-
-@note Do not add board specific header files/information here.
-*/
-
-/** @page dev_s3c24xx_mach Samsung's S3C24xx based platforms
-
-@par barebox Map
-
-The location of the @a barebox itself depends on the available amount of
-installed SDRAM memory:
-
-- 0x30fc.0000 Start of @a barebox when 16MiB SDRAM is available
-- 0x31fc.0000 Start of @a barebox when 32MiB SDRAM is available
-- 0x33fc.0000 Start of @a barebox when 64MiB SDRAM is available
-
-Adjust the @p CONFIG_TEXT_BASE/CONFIG_ARCH_TEXT_BASE symbol in accordance to
-the available memory.
-
-@note The RAM based filesystem and the stack resides always below the
-@a barebox start address.
-
-@li @subpage dev_s3c24xx_wd_handling
-@li @subpage dev_s3c24xx_pll_handling
-@li @subpage dev_s3c24xx_sdram_handling
-@li @subpage dev_s3c24xx_nandboot_handling
-*/
diff --git a/arch/arm/mach-samsung/gpio-s3c24x0.c b/arch/arm/mach-samsung/gpio-s3c24x0.c
index 4f1c5cc..baeaf4f 100644
--- a/arch/arm/mach-samsung/gpio-s3c24x0.c
+++ b/arch/arm/mach-samsung/gpio-s3c24x0.c
@@ -20,7 +20,7 @@
#include <io.h>
#include <mach/s3c-iomap.h>
#include <mach/gpio.h>
-#include <mach/s3c24xx-gpio.h>
+#include <mach/gpio-s3c24x0.h>
static const unsigned char group_offset[] =
{
diff --git a/arch/arm/mach-samsung/include/mach/clocks-s3c24x0.h b/arch/arm/mach-samsung/include/mach/clocks-s3c24x0.h
new file mode 100644
index 0000000..839dfe3
--- /dev/null
+++ b/arch/arm/mach-samsung/include/mach/clocks-s3c24x0.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2011 Juergen Beisert, Pengutronix
+ *
+ * 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.
+ */
+
+# define S3C_LOCKTIME (S3C_CLOCK_POWER_BASE)
+# define S3C_MPLLCON (S3C_CLOCK_POWER_BASE + 0x4)
+# define S3C_UPLLCON (S3C_CLOCK_POWER_BASE + 0x8)
+# define S3C_CLKCON (S3C_CLOCK_POWER_BASE + 0xc)
+# define S3C_CLKSLOW (S3C_CLOCK_POWER_BASE + 0x10)
+# define S3C_CLKDIVN (S3C_CLOCK_POWER_BASE + 0x14)
+
+# define S3C_MPLLCON_GET_MDIV(x) ((((x) >> 12) & 0xff) + 8)
+# define S3C_MPLLCON_GET_PDIV(x) ((((x) >> 4) & 0x3f) + 2)
+# define S3C_MPLLCON_GET_SDIV(x) ((x) & 0x3)
diff --git a/arch/arm/mach-samsung/include/mach/gpio-s3c24x0.h b/arch/arm/mach-samsung/include/mach/gpio-s3c24x0.h
new file mode 100644
index 0000000..ffb57fb
--- /dev/null
+++ b/arch/arm/mach-samsung/include/mach/gpio-s3c24x0.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2011 Juergen Beisert, Pengutronix
+ *
+ * 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.
+ */
+
+#ifndef __MACH_GPIO_S3C24X0_H
+# define __MACH_GPIO_S3C24X0_H
+
+#define S3C_GPACON (S3C_GPIO_BASE)
+#define S3C_GPADAT (S3C_GPIO_BASE + 0x04)
+
+#define S3C_GPBCON (S3C_GPIO_BASE + 0x10)
+#define S3C_GPBDAT (S3C_GPIO_BASE + 0x14)
+#define S3C_GPBUP (S3C_GPIO_BASE + 0x18)
+
+#define S3C_GPCCON (S3C_GPIO_BASE + 0x20)
+#define S3C_GPCDAT (S3C_GPIO_BASE + 0x24)
+#define S3C_GPCUP (S3C_GPIO_BASE + 0x28)
+
+#define S3C_GPDCON (S3C_GPIO_BASE + 0x30)
+#define S3C_GPDDAT (S3C_GPIO_BASE + 0x34)
+#define S3C_GPDUP (S3C_GPIO_BASE + 0x38)
+
+#define S3C_GPECON (S3C_GPIO_BASE + 0x40)
+#define S3C_GPEDAT (S3C_GPIO_BASE + 0x44)
+#define S3C_GPEUP (S3C_GPIO_BASE + 0x48)
+
+#define S3C_GPFCON (S3C_GPIO_BASE + 0x50)
+#define S3C_GPFDAT (S3C_GPIO_BASE + 0x54)
+#define S3C_GPFUP (S3C_GPIO_BASE + 0x58)
+
+#define S3C_GPGCON (S3C_GPIO_BASE + 0x60)
+#define S3C_GPGDAT (S3C_GPIO_BASE + 0x64)
+#define S3C_GPGUP (S3C_GPIO_BASE + 0x68)
+
+#define S3C_GPHCON (S3C_GPIO_BASE + 0x70)
+#define S3C_GPHDAT (S3C_GPIO_BASE + 0x74)
+#define S3C_GPHUP (S3C_GPIO_BASE + 0x78)
+
+#ifdef CONFIG_CPU_S3C2440
+# define S3C_GPJCON (S3C_GPIO_BASE + 0xd0)
+# define S3C_GPJDAT (S3C_GPIO_BASE + 0xd4)
+# define S3C_GPJUP (S3C_GPIO_BASE + 0xd8)
+#endif
+
+#define S3C_MISCCR (S3C_GPIO_BASE + 0x80)
+#define S3C_DCLKCON (S3C_GPIO_BASE + 0x84)
+#define S3C_EXTINT0 (S3C_GPIO_BASE + 0x88)
+#define S3C_EXTINT1 (S3C_GPIO_BASE + 0x8c)
+#define S3C_EXTINT2 (S3C_GPIO_BASE + 0x90)
+#define S3C_EINTFLT0 (S3C_GPIO_BASE + 0x94)
+#define S3C_EINTFLT1 (S3C_GPIO_BASE + 0x98)
+#define S3C_EINTFLT2 (S3C_GPIO_BASE + 0x9c)
+#define S3C_EINTFLT3 (S3C_GPIO_BASE + 0xa0)
+#define S3C_EINTMASK (S3C_GPIO_BASE + 0xa4)
+#define S3C_EINTPEND (S3C_GPIO_BASE + 0xa8)
+#define S3C_GSTATUS0 (S3C_GPIO_BASE + 0xac)
+#define S3C_GSTATUS1 (S3C_GPIO_BASE + 0xb0)
+#define S3C_GSTATUS2 (S3C_GPIO_BASE + 0xb4)
+#define S3C_GSTATUS3 (S3C_GPIO_BASE + 0xb8)
+#define S3C_GSTATUS4 (S3C_GPIO_BASE + 0xbc)
+
+#ifdef CONFIG_CPU_S3C2440
+# define S3C_DSC0 (S3C_GPIO_BASE + 0xc4)
+# define S3C_DSC1 (S3C_GPIO_BASE + 0xc8)
+#endif
+
+#endif /* __MACH_GPIO_S3C24X0_H */
diff --git a/arch/arm/mach-samsung/include/mach/iomap-s3c24x0.h b/arch/arm/mach-samsung/include/mach/iomap-s3c24x0.h
new file mode 100644
index 0000000..60d44e3
--- /dev/null
+++ b/arch/arm/mach-samsung/include/mach/iomap-s3c24x0.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009 Juergen Beisert, Pengutronix
+ *
+ * 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
+ *
+ */
+
+/* S3C2410 device base addresses */
+#define S3C_MEMCTL_BASE 0x48000000
+#define S3C2410_USB_HOST_BASE 0x49000000
+#define S3C2410_INTERRUPT_BASE 0x4A000000
+#define S3C2410_DMA_BASE 0x4B000000
+#define S3C_CLOCK_POWER_BASE 0x4C000000
+#define S3C2410_LCD_BASE 0x4D000000
+#define S3C24X0_NAND_BASE 0x4E000000
+#define S3C_UART_BASE 0x50000000
+#define S3C_TIMER_BASE 0x51000000
+#define S3C2410_USB_DEVICE_BASE 0x52000140
+#define S3C_WATCHDOG_BASE 0x53000000
+#define S3C2410_I2C_BASE 0x54000000
+#define S3C2410_I2S_BASE 0x55000000
+#define S3C_GPIO_BASE 0x56000000
+#define S3C2410_RTC_BASE 0x57000000
+#define S3C2410_ADC_BASE 0x58000000
+#define S3C2410_SPI_BASE 0x59000000
+#define S3C2410_SDI_BASE 0x5A000000
+
+/* external IO space */
+#define S3C_CS0_BASE 0x00000000
+#define S3C_CS1_BASE 0x08000000
+#define S3C_CS2_BASE 0x10000000
+#define S3C_CS3_BASE 0x18000000
+#define S3C_CS4_BASE 0x20000000
+#define S3C_CS5_BASE 0x28000000
+#define S3C_CS6_BASE 0x30000000
+
+#define S3C_SDRAM_BASE S3C_CS6_BASE
+#define S3C_SDRAM_END (S3C_SDRAM_BASE + 0x10000000)
+
+/*
+ * if we are booting from NAND, its internal SRAM occures at
+ * a different address than without this feature
+ */
+#ifdef CONFIG_S3C_NAND_BOOT
+# define NFC_RAM_AREA 0x00000000
+#else
+# define NFC_RAM_AREA 0x40000000
+#endif
+#define NFC_RAM_SIZE 4096
+
+#define S3C_UART1_BASE (S3C_UART_BASE)
+#define S3C_UART1_SIZE 0x4000
+#define S3C_UART2_BASE (S3C_UART_BASE + 0x4000)
+#define S3C_UART2_SIZE 0x4000
+#define S3C_UART3_BASE (S3C_UART_BASE + 0x8000)
+#define S3C_UART3_SIZE 0x4000
diff --git a/arch/arm/mach-samsung/include/mach/s3c-clocks.h b/arch/arm/mach-samsung/include/mach/s3c-clocks.h
index 44b2a6c..f4ca8fa 100644
--- a/arch/arm/mach-samsung/include/mach/s3c-clocks.h
+++ b/arch/arm/mach-samsung/include/mach/s3c-clocks.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2011 Juergen Beisert, Pengutronix
+ * 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
@@ -10,22 +11,19 @@
* 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 __MACH_S3C_CLOCKS_H
-# define __MACH_S3C_CLOCKS_H
+#define __MACH_S3C_CLOCKS_H
#ifdef CONFIG_ARCH_S3C24xx
-# define S3C_LOCKTIME (S3C_CLOCK_POWER_BASE)
-# define S3C_MPLLCON (S3C_CLOCK_POWER_BASE + 0x4)
-# define S3C_UPLLCON (S3C_CLOCK_POWER_BASE + 0x8)
-# define S3C_CLKCON (S3C_CLOCK_POWER_BASE + 0xc)
-# define S3C_CLKSLOW (S3C_CLOCK_POWER_BASE + 0x10)
-# define S3C_CLKDIVN (S3C_CLOCK_POWER_BASE + 0x14)
-
-# define S3C_MPLLCON_GET_MDIV(x) ((((x) >> 12) & 0xff) + 8)
-# define S3C_MPLLCON_GET_PDIV(x) ((((x) >> 4) & 0x3f) + 2)
-# define S3C_MPLLCON_GET_SDIV(x) ((x) & 0x3)
+# include <mach/clocks-s3c24x0.h>
#endif
#endif /* __MACH_S3C_CLOCKS_H */
diff --git a/arch/arm/mach-samsung/include/mach/s3c-generic.h b/arch/arm/mach-samsung/include/mach/s3c-generic.h
index 5d3808e..62d2c93 100644
--- a/arch/arm/mach-samsung/include/mach/s3c-generic.h
+++ b/arch/arm/mach-samsung/include/mach/s3c-generic.h
@@ -33,6 +33,8 @@ uint32_t s3c_get_uclk(void);
unsigned s3c_get_uart_clk(unsigned src);
-uint32_t s3c24xx_get_memory_size(void);
+uint32_t s3c_get_memory_size(void);
+#ifdef CONFIG_ARCH_S3C24xx
void s3c24xx_disable_second_sdram_bank(void);
+#endif
diff --git a/arch/arm/mach-samsung/include/mach/s3c-iomap.h b/arch/arm/mach-samsung/include/mach/s3c-iomap.h
index 9e867f8..b1305da 100644
--- a/arch/arm/mach-samsung/include/mach/s3c-iomap.h
+++ b/arch/arm/mach-samsung/include/mach/s3c-iomap.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2009 Juergen Beisert, Pengutronix
+ * 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
@@ -18,52 +19,6 @@
*
*/
-/* S3C2410 device base addresses */
-#define S3C_MEMCTL_BASE 0x48000000
-#define S3C2410_USB_HOST_BASE 0x49000000
-#define S3C2410_INTERRUPT_BASE 0x4A000000
-#define S3C2410_DMA_BASE 0x4B000000
-#define S3C_CLOCK_POWER_BASE 0x4C000000
-#define S3C2410_LCD_BASE 0x4D000000
-#define S3C24X0_NAND_BASE 0x4E000000
-#define S3C_UART_BASE 0x50000000
-#define S3C_TIMER_BASE 0x51000000
-#define S3C2410_USB_DEVICE_BASE 0x52000140
-#define S3C_WATCHDOG_BASE 0x53000000
-#define S3C2410_I2C_BASE 0x54000000
-#define S3C2410_I2S_BASE 0x55000000
-#define S3C_GPIO_BASE 0x56000000
-#define S3C2410_RTC_BASE 0x57000000
-#define S3C2410_ADC_BASE 0x58000000
-#define S3C2410_SPI_BASE 0x59000000
-#define S3C2410_SDI_BASE 0x5A000000
-
-/* external IO space */
-#define S3C_CS0_BASE 0x00000000
-#define S3C_CS1_BASE 0x08000000
-#define S3C_CS2_BASE 0x10000000
-#define S3C_CS3_BASE 0x18000000
-#define S3C_CS4_BASE 0x20000000
-#define S3C_CS5_BASE 0x28000000
-#define S3C_CS6_BASE 0x30000000
-
-#define S3C_SDRAM_BASE S3C_CS6_BASE
-#define S3C_SDRAM_END (S3C_SDRAM_BASE + 0x10000000)
-
-/*
- * if we are booting from NAND, its internal SRAM occures at
- * a different address than without this feature
- */
-#ifdef CONFIG_S3C24XX_NAND_BOOT
-# define NFC_RAM_AREA 0x00000000
-#else
-# define NFC_RAM_AREA 0x40000000
+#ifdef CONFIG_ARCH_S3C24xx
+# include <mach/iomap-s3c24x0.h>
#endif
-#define NFC_RAM_SIZE 4096
-
-#define S3C_UART1_BASE (S3C_UART_BASE)
-#define S3C_UART1_SIZE 0x4000
-#define S3C_UART2_BASE (S3C_UART_BASE + 0x4000)
-#define S3C_UART2_SIZE 0x4000
-#define S3C_UART3_BASE (S3C_UART_BASE + 0x8000)
-#define S3C_UART3_SIZE 0x4000
diff --git a/arch/arm/mach-samsung/include/mach/s3c-nand.h b/arch/arm/mach-samsung/include/mach/s3c-nand.h
new file mode 100644
index 0000000..51d0387
--- /dev/null
+++ b/arch/arm/mach-samsung/include/mach/s3c-nand.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 Juergen Beisert, Pengutronix
+ *
+ * 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
+ *
+ */
+
+#ifdef CONFIG_S3C_NAND_BOOT
+extern void s3c_nand_load_image(void*, int, int);
+#endif
+
+/**
+ * Locate the timing bits for the NFCONF register
+ * @param setup is the TACLS clock count
+ * @param access is the TWRPH0 clock count
+ * @param hold is the TWRPH1 clock count
+ *
+ * @note A clock count of 0 means always 1 HCLK clock.
+ * @note Clock count settings depend on the NAND flash requirements and the current HCLK speed
+ */
+#ifdef CONFIG_CPU_S3C2410
+# define CALC_NFCONF_TIMING(setup, access, hold) \
+ ((setup << 8) + (access << 4) + (hold << 0))
+#endif
+#ifdef CONFIG_CPU_S3C2440
+# define CALC_NFCONF_TIMING(setup, access, hold) \
+ ((setup << 12) + (access << 8) + (hold << 4))
+#endif
+
+/**
+ * Define platform specific data for the NAND controller and its device
+ */
+struct s3c_nand_platform_data {
+ uint32_t nand_timing; /**< value for the NFCONF register (timing bits only) */
+ char flash_bbt; /**< force a flash based BBT */
+};
+
+/**
+ * @file
+ * @brief Basic declaration to use the s3c24x0 NAND driver
+ */
diff --git a/arch/arm/mach-samsung/include/mach/s3c24xx-gpio.h b/arch/arm/mach-samsung/include/mach/s3c24xx-gpio.h
deleted file mode 100644
index c835974..0000000
--- a/arch/arm/mach-samsung/include/mach/s3c24xx-gpio.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2011 Juergen Beisert, Pengutronix
- *
- * 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.
- */
-
-#ifndef __MACH_S3C24XX_GPIO_H
-# define __MACH_S3C24XX_GPIO_H
-
-#define S3C_GPACON (S3C_GPIO_BASE)
-#define S3C_GPADAT (S3C_GPIO_BASE + 0x04)
-
-#define S3C_GPBCON (S3C_GPIO_BASE + 0x10)
-#define S3C_GPBDAT (S3C_GPIO_BASE + 0x14)
-#define S3C_GPBUP (S3C_GPIO_BASE + 0x18)
-
-#define S3C_GPCCON (S3C_GPIO_BASE + 0x20)
-#define S3C_GPCDAT (S3C_GPIO_BASE + 0x24)
-#define S3C_GPCUP (S3C_GPIO_BASE + 0x28)
-
-#define S3C_GPDCON (S3C_GPIO_BASE + 0x30)
-#define S3C_GPDDAT (S3C_GPIO_BASE + 0x34)
-#define S3C_GPDUP (S3C_GPIO_BASE + 0x38)
-
-#define S3C_GPECON (S3C_GPIO_BASE + 0x40)
-#define S3C_GPEDAT (S3C_GPIO_BASE + 0x44)
-#define S3C_GPEUP (S3C_GPIO_BASE + 0x48)
-
-#define S3C_GPFCON (S3C_GPIO_BASE + 0x50)
-#define S3C_GPFDAT (S3C_GPIO_BASE + 0x54)
-#define S3C_GPFUP (S3C_GPIO_BASE + 0x58)
-
-#define S3C_GPGCON (S3C_GPIO_BASE + 0x60)
-#define S3C_GPGDAT (S3C_GPIO_BASE + 0x64)
-#define S3C_GPGUP (S3C_GPIO_BASE + 0x68)
-
-#define S3C_GPHCON (S3C_GPIO_BASE + 0x70)
-#define S3C_GPHDAT (S3C_GPIO_BASE + 0x74)
-#define S3C_GPHUP (S3C_GPIO_BASE + 0x78)
-
-#ifdef CONFIG_CPU_S3C2440
-# define S3C_GPJCON (S3C_GPIO_BASE + 0xd0)
-# define S3C_GPJDAT (S3C_GPIO_BASE + 0xd4)
-# define S3C_GPJUP (S3C_GPIO_BASE + 0xd8)
-#endif
-
-#define S3C_MISCCR (S3C_GPIO_BASE + 0x80)
-#define S3C_DCLKCON (S3C_GPIO_BASE + 0x84)
-#define S3C_EXTINT0 (S3C_GPIO_BASE + 0x88)
-#define S3C_EXTINT1 (S3C_GPIO_BASE + 0x8c)
-#define S3C_EXTINT2 (S3C_GPIO_BASE + 0x90)
-#define S3C_EINTFLT0 (S3C_GPIO_BASE + 0x94)
-#define S3C_EINTFLT1 (S3C_GPIO_BASE + 0x98)
-#define S3C_EINTFLT2 (S3C_GPIO_BASE + 0x9c)
-#define S3C_EINTFLT3 (S3C_GPIO_BASE + 0xa0)
-#define S3C_EINTMASK (S3C_GPIO_BASE + 0xa4)
-#define S3C_EINTPEND (S3C_GPIO_BASE + 0xa8)
-#define S3C_GSTATUS0 (S3C_GPIO_BASE + 0xac)
-#define S3C_GSTATUS1 (S3C_GPIO_BASE + 0xb0)
-#define S3C_GSTATUS2 (S3C_GPIO_BASE + 0xb4)
-#define S3C_GSTATUS3 (S3C_GPIO_BASE + 0xb8)
-#define S3C_GSTATUS4 (S3C_GPIO_BASE + 0xbc)
-
-#ifdef CONFIG_CPU_S3C2440
-# define S3C_DSC0 (S3C_GPIO_BASE + 0xc4)
-# define S3C_DSC1 (S3C_GPIO_BASE + 0xc8)
-#endif
-
-#endif /* __MACH_S3C24XX_GPIO_H */
diff --git a/arch/arm/mach-samsung/include/mach/s3c24xx-nand.h b/arch/arm/mach-samsung/include/mach/s3c24xx-nand.h
deleted file mode 100644
index 7610b4e..0000000
--- a/arch/arm/mach-samsung/include/mach/s3c24xx-nand.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2009 Juergen Beisert, Pengutronix
- *
- * 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
- *
- */
-
-#ifdef CONFIG_S3C24XX_NAND_BOOT
-extern void s3c24x0_nand_load_image(void*, int, int);
-#endif
-
-/**
- * Locate the timing bits for the NFCONF register
- * @param setup is the TACLS clock count
- * @param access is the TWRPH0 clock count
- * @param hold is the TWRPH1 clock count
- *
- * @note A clock count of 0 means always 1 HCLK clock.
- * @note Clock count settings depend on the NAND flash requirements and the current HCLK speed
- */
-#ifdef CONFIG_CPU_S3C2410
-# define CALC_NFCONF_TIMING(setup, access, hold) \
- ((setup << 8) + (access << 4) + (hold << 0))
-#endif
-#ifdef CONFIG_CPU_S3C2440
-# define CALC_NFCONF_TIMING(setup, access, hold) \
- ((setup << 12) + (access << 8) + (hold << 4))
-#endif
-
-/**
- * Define platform specific data for the NAND controller and its device
- */
-struct s3c24x0_nand_platform_data {
- uint32_t nand_timing; /**< value for the NFCONF register (timing bits only) */
- char flash_bbt; /**< force a flash based BBT */
-};
-
-/**
- * @file
- * @brief Basic declaration to use the s3c24x0 NAND driver
- */
diff --git a/arch/arm/mach-samsung/lowlevel-init.S b/arch/arm/mach-samsung/lowlevel-init.S
deleted file mode 100644
index 31c6196..0000000
--- a/arch/arm/mach-samsung/lowlevel-init.S
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * (C) Copyright 2009
- * Juergen Beisert <kernel@pengutronix.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
- */
-
-#include <config.h>
-#include <mach/s3c-iomap.h>
-
- .section ".text_bare_init.s3c24x0_disable_wd","ax"
-
-/*
- * Disable the watchdog, else it continues to bark
- */
-.globl s3c24x0_disable_wd
-s3c24x0_disable_wd:
-
- ldr r0, =S3C_WATCHDOG_BASE
- mov r1, #0x0
- str r1, [r0]
- mov pc, lr
-
-/**
-@page dev_s3c24xx_wd_handling Watchdog handling
-
-The watchdog must be disabled very early, because if it resets the system
-it is still active and will continue to reset the system. So, call this
-routine very early in your board_init_lowlevel routine.
-*/
-
-/*
- * S3C2410 PLL configuration
- * -------------------------
- *
- * Basic frequency calculation
- *
- * m * REFclk s = SDIV
- * PLLclk = ------------ p = PDIV + 2
- * p * 2^s m = MDIV + 8
- *
- * After reset the PLL of the s3c2410 processor uses:
- *
- * MPLL UPLL
- * MDIV 0x5c 0x28
- * PDIV 0x08 0x08
- * SDIV 0x0 0x0
- *
- * 100 * 12MHz 1200MHz
- * MPLLclk = ------------- = -------- = 120MHz
- * 10 * 2^0 10
- *
- * 48 * 12MHz 576MHz
- * UPLLclk = ------------- = -------- = 57,6MHz
- * 10 * 2^0 10
- *
- * Note: Do not use "r10" here in this code
- */
-
-#ifdef CONFIG_S3C24XX_PLL_INIT
-
- .section ".text_bare_init.s3c24x0_pll_init","ax"
-
-.globl s3c24x0_pll_init
-s3c24x0_pll_init:
-
- mov r0, #S3C_CLOCK_POWER_BASE
-
- /* configure internal clock ratio */
- mov r1, #BOARD_SPECIFIC_CLKDIVN
- str r1, [r0, #20]
-
- /* enable all devices on this chip */
- mov r1, #0xFFFFFFF0
- str r1, [r0, #12]
-
- /* ??????? */
-#ifdef CONFIG_CPU_S3C2440
- mov r1, #0xFFFFFFFF
-#endif
-#ifdef CONFIG_CPU_S3C2410
- mov r1, #0x00FFFFFF
-#endif
- str r1, [r0, #0]
-
-#ifdef CONFIG_CPU_S3C2440
- /*
- * Most of the time HDIVN is not 0, so we must use the
- * asynchronous bus mode (refer datasheet "Clock and Power Management")
- */
- mrc p15, 0, r1, c1, c0, 0
- orr r1, r1, #0xc0000000
- mcr p15, 0, r1, c1, c0, 0
-#endif
-
- /* configure UPLL */
- ldr r1, =BOARD_SPECIFIC_UPLL
- str r1, [r0, #8]
-
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-
- /* configure MPLL */
- ldr r1, =BOARD_SPECIFIC_MPLL
- str r1, [r0, #4]
-
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-
- mov pc, lr
-
-#endif
-
-/**
-@page dev_s3c24xx_pll_handling PLL clock handling
-
-To control the speed of your machine the PLLs must be reconfigured after reset.
-
-For example the S3C2410 CPU wakes up after reset at 120MHz main PLL speed,
-shared with all other system on chip components. Most of the time this
-configuration is to slow for the CPU and to fast for the other components.
-
-PLL reprogramming can be done in the machine specific manner very early when
-the CONFIG_S3C24XX_PLL_INIT and CONFIG_MACH_HAS_LOWLEVEL_INIT symbols are
-defined. The board must provide a board_init_lowlevel() assembler function in
-this case and calling the s3c24x0_pll_init() assembler function.
-
-If the s3c24x0_pll_init() is called a few further symbols must be defined to
-setup the correct values for the machine.
-
-Define in the machine specific config.h the following symbols:
-
-- S3C24XX_CLOCK_REFERENCE with the frequency in Hz of your reference crystal.
-- BOARD_SPECIFIC_CLKDIVN with the value for the main clock ratio register (CLKDIVN)
-- BOARD_SPECIFIC_MPLL with the value for the main PLL setup register
-- BOARD_SPECIFIC_UPLL with the value for the USB PLL setup register
-
-@note Valid values for the PLL settings can be found in the CPU manual.
-
-@par Background: PLL frequency calculation for the S3C2410 CPU (both PLLs) and S3C2440 (UPLL only)
-
-@f[
- f_{PLL} = \frac{m * f_{Ref}}{p * 2^s}
-@f]
-
-With m = MDIV + 8, p = PDIV + 2 and s = SDIV.
-
-@par Background: PLL frequency calculation for the S3C2440 CPU (MPLL only)
-
-@f[
- f_{PLL} = \frac{2 * m * f_{Ref}}{p * 2^s}
-@f]
-
-With m = MDIV + 8, p = PDIV + 2 and s = SDIV.
-
-@note This routine can be used for the S3C2410 and the S3C2440 CPU.
-
-*/
-
-/* ----------------------------------------------------------------------- */
-
-#ifdef CONFIG_S3C24XX_SDRAM_INIT
-
- .section ".text_bare_init.s3c24x0_sdram_init","ax"
-
- .globl s3c24x0_sdram_init
-s3c24x0_sdram_init:
-
- adr r0, SDRAMDATA /* get the current relative address of the table */
- mov r1, #S3C_MEMCTL_BASE
- mov r2, #6 /* we *know* it contains 6 entries */
-
- ldr r3, [r0], #4 /* write BSWCON first */
- str r3, [r1], #0x1c /* post add register offset for bank6 */
-/*
- * Initializing the SDRAM controller is very simple:
- * Just write some useful values into the SDRAM controller.
- */
-0: ldr r3, [r0], #4
- str r3, [r1], #4
- subs r2, r2, #1
- bne 0b
-
- mov pc, lr
-
-SDRAMDATA:
- .word BOARD_SPECIFIC_BWSCON
- .word BOARD_SPECIFIC_BANKCON6
- .word BOARD_SPECIFIC_BANKCON7
- .word BOARD_SPECIFIC_REFRESH
- .word BOARD_SPECIFIC_BANKSIZE
- .word BOARD_SPECIFIC_MRSRB6
- .word BOARD_SPECIFIC_MRSRB7
-
-#endif
-
-/**
-@page dev_s3c24xx_sdram_handling SDRAM controller initialisation
-
-The SDRAM controller is very simple and its initialisation requires only a
-few steps. barebox provides a generic routine to do this step.
-
-Enable CONFIG_S3C24XX_SDRAM_INIT and CONFIG_MACH_HAS_LOWLEVEL_INIT to be able
-to call the generic s3c24x0_sdram_init() assembler function from within the
-machine specific board_init_lowlevel() assembler function.
-
-To use the s3c24x0_sdram_init() assembler function a few symbols must be
-defined to setup correct values for the machine.
-
-Define in the machine specific config.h the following list of symbols:
-
-- BOARD_SPECIFIC_BWSCON with the values for SDRAM banks 6 and 7
-- BOARD_SPECIFIC_BANKCON6 with the value for the BANKCON6 register
-- BOARD_SPECIFIC_BANKCON7 with the value for the BANKCON7 register
-- BOARD_SPECIFIC_REFRESH with the value for the REFRESH register
-- BOARD_SPECIFIC_BANKSIZE with the value for the BANKSIZE register
-- BOARD_SPECIFIC_MRSRB6 with the value for the MRSRB6 register
-- BOARD_SPECIFIC_MRSRB7 with the value for the MRSRB7 register
-*/
-
-/* ----------------------------------------------------------------------- */
-
-#ifdef CONFIG_S3C24XX_NAND_BOOT
-
- .section ".text_bare_init.s3c24x0_nand_boot","ax"
-
- .globl s3c24x0_nand_boot
-s3c24x0_nand_boot:
-/*
- * In the case of NOR boot we are running from the same address space.
- * Detect this case to handle it correctly.
- */
- mov r1, #S3C_MEMCTL_BASE
- ldr r3, [r1]
- and r3, r3, #0x6
- cmp r3, #0x0 /* check for NAND case */
- beq 2f
- mov pc, lr /* NOR case: nothing to do here */
-
-2: ldr sp, =TEXT_BASE /* Setup a temporary stack in SDRAM */
-/*
- * We still run at a location we are not linked to. But lets still running
- * from the internal SRAM, this may speed up the boot
- */
- push {lr}
- bl nand_boot
- pop {lr}
-/*
- * Adjust the return address to the correct address in SDRAM
- */
- ldr r1, =TEXT_BASE
- add lr, lr, r1
-
- mov pc, lr
-
-#endif
-
-/**
-@page dev_s3c24xx_nandboot_handling Booting from NAND
-
-To be able to boot from NAND memory only, enable the S3C24x0 NAND driver. Also
-enable CONFIG_S3C24XX_NAND_BOOT and CONFIG_MACH_HAS_LOWLEVEL_INIT to be
-able to call the s3c24x0_nand_boot() assembler routine from within the
-machine specific board_init_lowlevel() assembler function.
-
-@note This routine assumes an already working SDRAM controller and
-an initialized stack pointer.
-
-@note Basicly this routine runs from inside the internal SRAM. After load of
-the whole barebox image from the NAND flash memory into the SDRAM it adjusts
-the link register to the final SDRAM adress and returns.
-
-@note In the NAND boot mode, ECC is not checked. So, the first x KBytes used
-by barebox should have no bit error.
-
-Due to the fact the code to load the whole barebox from NAND must fit into
-the first 4kiB of the barebox image, the shrinked NAND driver is very
-minimalistic. Setup the NAND access timing is done in a safe manner, what
-means: Slowest possible values are used. If you want to increase the speed you
-should define the BOARD_DEFAULT_NAND_TIMING to a valid setting into the
-NFCONF register and add it to your board specific config.h. Refer S3C24x0's
-datasheet for further details. The macro #CALC_NFCONF_TIMING could help to
-calculate the register setting in a hardware independent manner.
-
-@note The regular NAND driver uses a platform data structure to define the
-NAND access timings.
-
-@note Its still possible to boot this image from NOR memory. If this routine
-detects it is running from NOR instead of the internal SRAM it skips any
-loading and returns immediately.
-
-*/
diff --git a/arch/arm/mach-samsung/lowlevel-s3c24x0.S b/arch/arm/mach-samsung/lowlevel-s3c24x0.S
new file mode 100644
index 0000000..e9471a5
--- /dev/null
+++ b/arch/arm/mach-samsung/lowlevel-s3c24x0.S
@@ -0,0 +1,317 @@
+/*
+ * (C) Copyright 2009
+ * Juergen Beisert <kernel@pengutronix.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
+ */
+
+#include <config.h>
+#include <mach/s3c-iomap.h>
+
+ .section ".text_bare_init.s3c24x0_disable_wd","ax"
+
+/*
+ * Disable the watchdog, else it continues to bark
+ */
+.globl s3c24x0_disable_wd
+s3c24x0_disable_wd:
+
+ ldr r0, =S3C_WATCHDOG_BASE
+ mov r1, #0x0
+ str r1, [r0]
+ mov pc, lr
+
+/**
+@page dev_s3c24xx_wd_handling Watchdog handling
+
+The watchdog must be disabled very early, because if it resets the system
+it is still active and will continue to reset the system. So, call this
+routine very early in your board_init_lowlevel routine.
+*/
+
+/*
+ * S3C2410 PLL configuration
+ * -------------------------
+ *
+ * Basic frequency calculation
+ *
+ * m * REFclk s = SDIV
+ * PLLclk = ------------ p = PDIV + 2
+ * p * 2^s m = MDIV + 8
+ *
+ * After reset the PLL of the s3c2410 processor uses:
+ *
+ * MPLL UPLL
+ * MDIV 0x5c 0x28
+ * PDIV 0x08 0x08
+ * SDIV 0x0 0x0
+ *
+ * 100 * 12MHz 1200MHz
+ * MPLLclk = ------------- = -------- = 120MHz
+ * 10 * 2^0 10
+ *
+ * 48 * 12MHz 576MHz
+ * UPLLclk = ------------- = -------- = 57,6MHz
+ * 10 * 2^0 10
+ *
+ * Note: Do not use "r10" here in this code
+ */
+
+#ifdef CONFIG_S3C_PLL_INIT
+
+ .section ".text_bare_init.s3c24x0_pll_init","ax"
+
+.globl s3c24x0_pll_init
+s3c24x0_pll_init:
+
+ mov r0, #S3C_CLOCK_POWER_BASE
+
+ /* configure internal clock ratio */
+ mov r1, #BOARD_SPECIFIC_CLKDIVN
+ str r1, [r0, #20]
+
+ /* enable all devices on this chip */
+ mov r1, #0xFFFFFFF0
+ str r1, [r0, #12]
+
+ /* ??????? */
+#ifdef CONFIG_CPU_S3C2440
+ mov r1, #0xFFFFFFFF
+#endif
+#ifdef CONFIG_CPU_S3C2410
+ mov r1, #0x00FFFFFF
+#endif
+ str r1, [r0, #0]
+
+#ifdef CONFIG_CPU_S3C2440
+ /*
+ * Most of the time HDIVN is not 0, so we must use the
+ * asynchronous bus mode (refer datasheet "Clock and Power Management")
+ */
+ mrc p15, 0, r1, c1, c0, 0
+ orr r1, r1, #0xc0000000
+ mcr p15, 0, r1, c1, c0, 0
+#endif
+
+ /* configure UPLL */
+ ldr r1, =BOARD_SPECIFIC_UPLL
+ str r1, [r0, #8]
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ /* configure MPLL */
+ ldr r1, =BOARD_SPECIFIC_MPLL
+ str r1, [r0, #4]
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ mov pc, lr
+
+#endif
+
+/**
+@page dev_s3c24xx_pll_handling PLL clock handling
+
+To control the speed of your machine the PLLs must be reconfigured after reset.
+
+For example the S3C2410 CPU wakes up after reset at 120MHz main PLL speed,
+shared with all other system on chip components. Most of the time this
+configuration is to slow for the CPU and to fast for the other components.
+
+PLL reprogramming can be done in the machine specific manner very early when
+the CONFIG_S3C_PLL_INIT and CONFIG_MACH_HAS_LOWLEVEL_INIT symbols are
+defined. The board must provide a board_init_lowlevel() assembler function in
+this case and calling the s3c24x0_pll_init() assembler function.
+
+If the s3c24x0_pll_init() is called a few further symbols must be defined to
+setup the correct values for the machine.
+
+Define in the machine specific config.h the following symbols:
+
+- S3C24XX_CLOCK_REFERENCE with the frequency in Hz of your reference crystal.
+- BOARD_SPECIFIC_CLKDIVN with the value for the main clock ratio register (CLKDIVN)
+- BOARD_SPECIFIC_MPLL with the value for the main PLL setup register
+- BOARD_SPECIFIC_UPLL with the value for the USB PLL setup register
+
+@note Valid values for the PLL settings can be found in the CPU manual.
+
+@par Background: PLL frequency calculation for the S3C2410 CPU (both PLLs) and S3C2440 (UPLL only)
+
+@f[
+ f_{PLL} = \frac{m * f_{Ref}}{p * 2^s}
+@f]
+
+With m = MDIV + 8, p = PDIV + 2 and s = SDIV.
+
+@par Background: PLL frequency calculation for the S3C2440 CPU (MPLL only)
+
+@f[
+ f_{PLL} = \frac{2 * m * f_{Ref}}{p * 2^s}
+@f]
+
+With m = MDIV + 8, p = PDIV + 2 and s = SDIV.
+
+@note This routine can be used for the S3C2410 and the S3C2440 CPU.
+
+*/
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_S3C_SDRAM_INIT
+
+ .section ".text_bare_init.s3c24x0_sdram_init","ax"
+
+ .globl s3c24x0_sdram_init
+s3c24x0_sdram_init:
+
+ adr r0, SDRAMDATA /* get the current relative address of the table */
+ mov r1, #S3C_MEMCTL_BASE
+ mov r2, #6 /* we *know* it contains 6 entries */
+
+ ldr r3, [r0], #4 /* write BSWCON first */
+ str r3, [r1], #0x1c /* post add register offset for bank6 */
+/*
+ * Initializing the SDRAM controller is very simple:
+ * Just write some useful values into the SDRAM controller.
+ */
+0: ldr r3, [r0], #4
+ str r3, [r1], #4
+ subs r2, r2, #1
+ bne 0b
+
+ mov pc, lr
+
+SDRAMDATA:
+ .word BOARD_SPECIFIC_BWSCON
+ .word BOARD_SPECIFIC_BANKCON6
+ .word BOARD_SPECIFIC_BANKCON7
+ .word BOARD_SPECIFIC_REFRESH
+ .word BOARD_SPECIFIC_BANKSIZE
+ .word BOARD_SPECIFIC_MRSRB6
+ .word BOARD_SPECIFIC_MRSRB7
+
+#endif
+
+/**
+@page dev_s3c24xx_sdram_handling SDRAM controller initialisation
+
+The SDRAM controller is very simple and its initialisation requires only a
+few steps. barebox provides a generic routine to do this step.
+
+Enable CONFIG_S3C_SDRAM_INIT and CONFIG_MACH_HAS_LOWLEVEL_INIT to be able
+to call the generic s3c24x0_sdram_init() assembler function from within the
+machine specific board_init_lowlevel() assembler function.
+
+To use the s3c24x0_sdram_init() assembler function a few symbols must be
+defined to setup correct values for the machine.
+
+Define in the machine specific config.h the following list of symbols:
+
+- BOARD_SPECIFIC_BWSCON with the values for SDRAM banks 6 and 7
+- BOARD_SPECIFIC_BANKCON6 with the value for the BANKCON6 register
+- BOARD_SPECIFIC_BANKCON7 with the value for the BANKCON7 register
+- BOARD_SPECIFIC_REFRESH with the value for the REFRESH register
+- BOARD_SPECIFIC_BANKSIZE with the value for the BANKSIZE register
+- BOARD_SPECIFIC_MRSRB6 with the value for the MRSRB6 register
+- BOARD_SPECIFIC_MRSRB7 with the value for the MRSRB7 register
+*/
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_S3C_NAND_BOOT
+
+ .section ".text_bare_init.s3c24x0_nand_boot","ax"
+
+ .globl s3c24x0_nand_boot
+s3c24x0_nand_boot:
+/*
+ * In the case of NOR boot we are running from the same address space.
+ * Detect this case to handle it correctly.
+ */
+ mov r1, #S3C_MEMCTL_BASE
+ ldr r3, [r1]
+ and r3, r3, #0x6
+ cmp r3, #0x0 /* check for NAND case */
+ beq 2f
+ mov pc, lr /* NOR case: nothing to do here */
+
+2: ldr sp, =TEXT_BASE /* Setup a temporary stack in SDRAM */
+/*
+ * We still run at a location we are not linked to. But lets still running
+ * from the internal SRAM, this may speed up the boot
+ */
+ push {lr}
+ bl nand_boot
+ pop {lr}
+/*
+ * Adjust the return address to the correct address in SDRAM
+ */
+ ldr r1, =TEXT_BASE
+ add lr, lr, r1
+
+ mov pc, lr
+
+#endif
+
+/**
+@page dev_s3c24xx_nandboot_handling Booting from NAND
+
+To be able to boot from NAND memory only, enable the S3C24x0 NAND driver. Also
+enable CONFIG_S3C_NAND_BOOT and CONFIG_MACH_HAS_LOWLEVEL_INIT to be
+able to call the s3c24x0_nand_boot() assembler routine from within the
+machine specific board_init_lowlevel() assembler function.
+
+@note This routine assumes an already working SDRAM controller and
+an initialized stack pointer.
+
+@note Basicly this routine runs from inside the internal SRAM. After load of
+the whole barebox image from the NAND flash memory into the SDRAM it adjusts
+the link register to the final SDRAM adress and returns.
+
+@note In the NAND boot mode, ECC is not checked. So, the first x KBytes used
+by barebox should have no bit error.
+
+Due to the fact the code to load the whole barebox from NAND must fit into
+the first 4kiB of the barebox image, the shrinked NAND driver is very
+minimalistic. Setup the NAND access timing is done in a safe manner, what
+means: Slowest possible values are used. If you want to increase the speed you
+should define the BOARD_DEFAULT_NAND_TIMING to a valid setting into the
+NFCONF register and add it to your board specific config.h. Refer S3C24x0's
+datasheet for further details. The macro #CALC_NFCONF_TIMING could help to
+calculate the register setting in a hardware independent manner.
+
+@note The regular NAND driver uses a platform data structure to define the
+NAND access timings.
+
+@note Its still possible to boot this image from NOR memory. If this routine
+detects it is running from NOR instead of the internal SRAM it skips any
+loading and returns immediately.
+
+*/
diff --git a/arch/arm/mach-samsung/mem-s3c24x0.c b/arch/arm/mach-samsung/mem-s3c24x0.c
new file mode 100644
index 0000000..6944504
--- /dev/null
+++ b/arch/arm/mach-samsung/mem-s3c24x0.c
@@ -0,0 +1,143 @@
+/*
+ * 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
+ */
+/**
+ * @file
+ * @brief Basic clock, sdram and timer handling for S3C24xx CPUs
+ */
+
+#include <config.h>
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <io.h>
+#include <sizes.h>
+#include <mach/s3c-iomap.h>
+#include <mach/s3c-generic.h>
+#include <mach/s3c-busctl.h>
+#include <mach/gpio-s3c24x0.h>
+
+/**
+ * Calculate the amount of connected and available memory
+ * @return Memory size in bytes
+ */
+uint32_t s3c_get_memory_size(void)
+{
+ uint32_t reg, size;
+
+ /*
+ * detect the current memory size
+ */
+ reg = readl(S3C_BANKSIZE);
+
+ switch (reg & 0x7) {
+ case 0:
+ size = SZ_32M;
+ break;
+ case 1:
+ size = SZ_64M;
+ break;
+ case 2:
+ size = SZ_128M;
+ break;
+ case 4:
+ size = SZ_2M;
+ break;
+ case 5:
+ size = SZ_4M;
+ break;
+ case 6:
+ size = SZ_8M;
+ break;
+ default:
+ size = SZ_16M;
+ break;
+ }
+
+ /*
+ * Is bank7 also configured for SDRAM usage?
+ */
+ if ((readl(S3C_BANKCON7) & (0x3 << 15)) == (0x3 << 15))
+ size <<= 1; /* also count this bank */
+
+ return size;
+}
+
+void s3c24xx_disable_second_sdram_bank(void)
+{
+ writel(readl(S3C_BANKCON7) & ~(0x3 << 15), S3C_BANKCON7);
+ writel(readl(S3C_MISCCR) | (1 << 18), S3C_MISCCR); /* disable its clock */
+}
+
+/**
+
+@page dev_s3c24xx_arch Samsung's S3C24xx Platforms in barebox
+
+@section s3c24xx_boards Boards using S3C24xx Processors
+
+@li @subpage arch/arm/boards/a9m2410/a9m2410.c
+@li @subpage arch/arm/boards/a9m2440/a9m2440.c
+
+@section s3c24xx_arch Documentation for S3C24xx Architectures Files
+
+@li @subpage arch/arm/mach-s3c24xx/generic.c
+
+@section s3c24xx_mem_map SDRAM Memory Map
+
+SDRAM starts at address 0x3000.0000 up to the available amount of connected
+SDRAM memory. Physically this CPU can handle up to 256MiB (two areas with
+up to 128MiB each).
+
+@subsection s3c24xx_mem_generic_map Generic Map
+- 0x0000.0000 Start of the internal SRAM when booting from NAND flash memory or CS signal to a NOR flash memory.
+- 0x0800.0000 Start of I/O space.
+- 0x3000.0000 Start of SDRAM area.
+ - 0x3000.0100 Start of the TAG list area.
+ - 0x3000.8000 Start of the linux kernel (physical address).
+- 0x4000.0000 Start of internal SRAM, when booting from NOR flash memory
+- 0x4800.0000 Start of the internal I/O area
+
+@section s3c24xx_asm_arm include/asm-arm/arch-s3c24xx directory guidelines
+All S3C24xx common headers are located here.
+
+@note Do not add board specific header files/information here.
+*/
+
+/** @page dev_s3c24xx_mach Samsung's S3C24xx based platforms
+
+@par barebox Map
+
+The location of the @a barebox itself depends on the available amount of
+installed SDRAM memory:
+
+- 0x30fc.0000 Start of @a barebox when 16MiB SDRAM is available
+- 0x31fc.0000 Start of @a barebox when 32MiB SDRAM is available
+- 0x33fc.0000 Start of @a barebox when 64MiB SDRAM is available
+
+Adjust the @p CONFIG_TEXT_BASE/CONFIG_ARCH_TEXT_BASE symbol in accordance to
+the available memory.
+
+@note The RAM based filesystem and the stack resides always below the
+@a barebox start address.
+
+@li @subpage dev_s3c24xx_wd_handling
+@li @subpage dev_s3c24xx_pll_handling
+@li @subpage dev_s3c24xx_sdram_handling
+@li @subpage dev_s3c24xx_nandboot_handling
+*/
diff --git a/arch/arm/mach-samsung/s3c24xx-clocks.c b/arch/arm/mach-samsung/s3c24xx-clocks.c
deleted file mode 100644
index 38d8b75..0000000
--- a/arch/arm/mach-samsung/s3c24xx-clocks.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.
- */
-
-#include <config.h>
-#include <common.h>
-#include <init.h>
-#include <clock.h>
-#include <io.h>
-#include <mach/s3c-iomap.h>
-#include <mach/s3c-generic.h>
-#include <mach/s3c-clocks.h>
-#include <mach/s3c-busctl.h>
-
-/**
- * Calculate the current M-PLL clock.
- * @return Current frequency in Hz
- */
-uint32_t s3c_get_mpllclk(void)
-{
- uint32_t m, p, s, reg_val;
-
- reg_val = readl(S3C_MPLLCON);
- m = ((reg_val & 0xFF000) >> 12) + 8;
- p = ((reg_val & 0x003F0) >> 4) + 2;
- s = reg_val & 0x3;
-#ifdef CONFIG_CPU_S3C2410
- return (S3C24XX_CLOCK_REFERENCE * m) / (p << s);
-#endif
-#ifdef CONFIG_CPU_S3C2440
- return 2 * m * (S3C24XX_CLOCK_REFERENCE / (p << s));
-#endif
-}
-
-/**
- * Calculate the current U-PLL clock
- * @return Current frequency in Hz
- */
-uint32_t s3c_get_upllclk(void)
-{
- uint32_t m, p, s, reg_val;
-
- reg_val = readl(S3C_UPLLCON);
- m = ((reg_val & 0xFF000) >> 12) + 8;
- p = ((reg_val & 0x003F0) >> 4) + 2;
- s = reg_val & 0x3;
-
- return (S3C24XX_CLOCK_REFERENCE * m) / (p << s);
-}
-
-/**
- * Calculate the FCLK frequency used for the ARM CPU core
- * @return Current frequency in Hz
- */
-uint32_t s3c_get_fclk(void)
-{
- return s3c_get_mpllclk();
-}
-
-/**
- * Calculate the HCLK frequency used for the AHB bus (CPU to main peripheral)
- * @return Current frequency in Hz
- */
-uint32_t s3c_get_hclk(void)
-{
- uint32_t f_clk;
-
- f_clk = s3c_get_fclk();
-#ifdef CONFIG_CPU_S3C2410
- if (readl(S3C_CLKDIVN) & 0x02)
- return f_clk >> 1;
-#endif
-#ifdef CONFIG_CPU_S3C2440
- switch(readl(S3C_CLKDIVN) & 0x06) {
- case 2:
- return f_clk >> 1;
- case 4:
- return f_clk >> 2; /* TODO consider CAMDIVN */
- case 6:
- return f_clk / 3; /* TODO consider CAMDIVN */
- }
-#endif
- return f_clk;
-}
-
-/**
- * Calculate the PCLK frequency used for the slower peripherals
- * @return Current frequency in Hz
- */
-uint32_t s3c_get_pclk(void)
-{
- uint32_t p_clk;
-
- p_clk = s3c_get_hclk();
- if (readl(S3C_CLKDIVN) & 0x01)
- return p_clk >> 1;
- return p_clk;
-}
-
-/**
- * Calculate the UCLK frequency used by the USB host device
- * @return Current frequency in Hz
- */
-uint32_t s3c24_get_uclk(void)
-{
- return s3c_get_upllclk();
-}
-
-/**
- * Return correct UART frequency based on the UCON register
- */
-unsigned s3c_get_uart_clk(unsigned src)
-{
- switch (src & 3) {
- case 0:
- case 2:
- return s3c_get_pclk();
- case 1:
- return 0; /* TODO UEXTCLK */
- case 3:
- return 0; /* TODO FCLK/n */
- }
- return 0; /* not reached, to make compiler happy */
-}
-
-/**
- * Show the user the current clock settings
- */
-int s3c24xx_dump_clocks(void)
-{
- printf("refclk: %7d kHz\n", S3C24XX_CLOCK_REFERENCE / 1000);
- printf("mpll: %7d kHz\n", s3c_get_mpllclk() / 1000);
- printf("upll: %7d kHz\n", s3c_get_upllclk() / 1000);
- printf("fclk: %7d kHz\n", s3c_get_fclk() / 1000);
- printf("hclk: %7d kHz\n", s3c_get_hclk() / 1000);
- printf("pclk: %7d kHz\n", s3c_get_pclk() / 1000);
- printf("SDRAM1: CL%d@%dMHz\n", ((readl(S3C_BANKCON6) & 0xc) >> 2) + 2,
- s3c_get_hclk() / 1000000);
- if ((readl(S3C_BANKCON7) & (0x3 << 15)) == (0x3 << 15))
- printf("SDRAM2: CL%d@%dMHz\n",
- ((readl(S3C_BANKCON7) & 0xc) >> 2) + 2,
- s3c_get_hclk() / 1000000);
- return 0;
-}
-
-late_initcall(s3c24xx_dump_clocks);
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 926a64b..f49417d 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -65,9 +65,9 @@ config NAND_ATMEL
prompt "Atmel (AT91SAM9xxx) NAND driver"
depends on ARCH_AT91
-config NAND_S3C24XX
+config NAND_S3C
bool
- prompt "Samsung S3C24XX NAND driver"
+ prompt "Samsung S3C NAND driver"
depends on ARCH_S3C24xx
help
Add support for processor's NAND device controller.
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 5c6d8b3..3e211d5 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -14,4 +14,4 @@ obj-$(CONFIG_MTD_NAND_NOMADIK) += nomadik_nand.o
obj-$(CONFIG_NAND_IMX) += nand_imx.o
obj-$(CONFIG_NAND_OMAP_GPMC) += nand_omap_gpmc.o nand_omap_bch_decoder.o
obj-$(CONFIG_NAND_ATMEL) += atmel_nand.o
-obj-$(CONFIG_NAND_S3C24XX) += nand_s3c24xx.o
+obj-$(CONFIG_NAND_S3C) += nand_s3c.o
diff --git a/drivers/mtd/nand/nand_s3c.c b/drivers/mtd/nand/nand_s3c.c
new file mode 100644
index 0000000..9b76f98
--- /dev/null
+++ b/drivers/mtd/nand/nand_s3c.c
@@ -0,0 +1,665 @@
+/* linux/drivers/mtd/nand/s3c2410.c
+ *
+ * Copyright (C) 2009 Juergen Beisert, Pengutronix
+ *
+ * Copyright © 2004-2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2410 NAND driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <config.h>
+#include <common.h>
+#include <driver.h>
+#include <malloc.h>
+#include <init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <mach/s3c-generic.h>
+#include <mach/s3c-iomap.h>
+#include <mach/s3c-nand.h>
+#include <io.h>
+#include <asm-generic/errno.h>
+
+#ifdef CONFIG_S3C_NAND_BOOT
+# define __nand_boot_init __bare_init
+# ifndef BOARD_DEFAULT_NAND_TIMING
+# define BOARD_DEFAULT_NAND_TIMING 0x0737
+# endif
+#else
+# define __nand_boot_init
+#endif
+
+/**
+ * Define this symbol for testing purpose. It will add a command to read an
+ * image from the NAND like it the boot strap code will do.
+ */
+#define CONFIG_NAND_S3C_BOOT_DEBUG
+
+/* NAND controller's register */
+
+#define NFCONF 0x00
+
+#ifdef CONFIG_CPU_S3C2410
+
+#define NFCMD 0x04
+#define NFADDR 0x08
+#define NFDATA 0x0c
+#define NFSTAT 0x10
+#define NFECC 0x14
+
+/* S3C2410 specific bits */
+#define NFSTAT_BUSY (1)
+#define NFCONF_nFCE (1 << 11)
+#define NFCONF_INITECC (1 << 12)
+#define NFCONF_EN (1 << 15)
+
+#endif /* CONFIG_CPU_S3C2410 */
+
+#ifdef CONFIG_CPU_S3C2440
+
+#define NFCONT 0x04
+#define NFCMD 0x08
+#define NFADDR 0x0C
+#define NFDATA 0x10
+#define NFSTAT 0x20
+#define NFECC 0x2C
+
+/* S3C2440 specific bits */
+#define NFSTAT_BUSY (1)
+#define NFCONT_nFCE (1 << 1)
+#define NFCONT_INITECC (1 << 4)
+#define NFCONT_EN (1)
+
+#endif /* CONFIG_CPU_S3C2440 */
+
+
+struct s3c24x0_nand_host {
+ struct mtd_info mtd;
+ struct nand_chip nand;
+ struct mtd_partition *parts;
+ struct device_d *dev;
+
+ void __iomem *base;
+};
+
+/**
+ * oob placement block for use with hardware ecc generation on small page
+ */
+static struct nand_ecclayout nand_hw_eccoob = {
+ .eccbytes = 3,
+ .eccpos = { 0, 1, 2},
+ .oobfree = {
+ {
+ .offset = 8,
+ .length = 8
+ }
+ }
+};
+
+/* - Functions shared between the boot strap code and the regular driver - */
+
+/**
+ * Issue the specified command to the NAND device
+ * @param[in] host Base address of the NAND controller
+ * @param[in] cmd Command for NAND flash
+ */
+static void __nand_boot_init send_cmd(void __iomem *host, uint8_t cmd)
+{
+ writeb(cmd, host + NFCMD);
+}
+
+/**
+ * Issue the specified address to the NAND device
+ * @param[in] host Base address of the NAND controller
+ * @param[in] addr Address for the NAND flash
+ */
+static void __nand_boot_init send_addr(void __iomem *host, uint8_t addr)
+{
+ writeb(addr, host + NFADDR);
+}
+
+/**
+ * Enable the NAND flash access
+ * @param[in] host Base address of the NAND controller
+ */
+static void __nand_boot_init enable_cs(void __iomem *host)
+{
+#ifdef CONFIG_CPU_S3C2410
+ writew(readw(host + NFCONF) & ~NFCONF_nFCE, host + NFCONF);
+#endif
+#ifdef CONFIG_CPU_S3C2440
+ writew(readw(host + NFCONT) & ~NFCONT_nFCE, host + NFCONT);
+#endif
+}
+
+/**
+ * Disable the NAND flash access
+ * @param[in] host Base address of the NAND controller
+ */
+static void __nand_boot_init disable_cs(void __iomem *host)
+{
+#ifdef CONFIG_CPU_S3C2410
+ writew(readw(host + NFCONF) | NFCONF_nFCE, host + NFCONF);
+#endif
+#ifdef CONFIG_CPU_S3C2440
+ writew(readw(host + NFCONT) | NFCONT_nFCE, host + NFCONT);
+#endif
+}
+
+/**
+ * Enable the NAND flash controller
+ * @param[in] host Base address of the NAND controller
+ * @param[in] timing Timing to access the NAND memory
+ */
+static void __nand_boot_init enable_nand_controller(void __iomem *host, uint32_t timing)
+{
+#ifdef CONFIG_CPU_S3C2410
+ writew(timing + NFCONF_EN + NFCONF_nFCE, host + NFCONF);
+#endif
+#ifdef CONFIG_CPU_S3C2440
+ writew(NFCONT_EN + NFCONT_nFCE, host + NFCONT);
+ writew(timing, host + NFCONF);
+#endif
+}
+
+/**
+ * Diable the NAND flash controller
+ * @param[in] host Base address of the NAND controller
+ */
+static void __nand_boot_init disable_nand_controller(void __iomem *host)
+{
+#ifdef CONFIG_CPU_S3C2410
+ writew(NFCONF_nFCE, host + NFCONF);
+#endif
+#ifdef CONFIG_CPU_S3C2440
+ writew(NFCONT_nFCE, host + NFCONT);
+#endif
+}
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_CPU_S3C2440
+/**
+ * Read one block of data from the NAND port
+ * @param[in] mtd Instance data
+ * @param[out] buf buffer to write data to
+ * @param[in] len byte count
+ *
+ * This is a special block read variant for the S3C2440 CPU.
+ */
+static void s3c2440_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct s3c24x0_nand_host *host = nand_chip->priv;
+
+ readsl(host->base + NFDATA, buf, len >> 2);
+
+ /* cleanup any fractional read */
+ if (len & 3) {
+ buf += len & ~3;
+
+ for (; len & 3; len--)
+ *buf++ = readb(host->base + NFDATA);
+ }
+}
+
+/**
+ * Write one block of data to the NAND port
+ * @param[in] mtd Instance data
+ * @param[out] buf buffer to read data from
+ * @param[in] len byte count
+ *
+ * This is a special block write variant for the S3C2440 CPU.
+ */
+static void s3c2440_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf,
+ int len)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct s3c24x0_nand_host *host = nand_chip->priv;
+
+ writesl(host->base + NFDATA, buf, len >> 2);
+
+ /* cleanup any fractional write */
+ if (len & 3) {
+ buf += len & ~3;
+
+ for (; len & 3; len--, buf++)
+ writeb(*buf, host->base + NFDATA);
+ }
+}
+#endif
+
+/**
+ * Check the ECC and try to repair the data if possible
+ * @param[in] mtd_info Not used
+ * @param[inout] dat Pointer to the data buffer that might contain a bit error
+ * @param[in] read_ecc ECC data from the OOB space
+ * @param[in] calc_ecc ECC data calculated from the data
+ * @return 0 no error, 1 repaired error, -1 no way...
+ *
+ * @note: This routine works always on a 24 bit ECC
+ */
+static int s3c2410_nand_correct_data(struct mtd_info *mtd, uint8_t *dat,
+ uint8_t *read_ecc, uint8_t *calc_ecc)
+{
+ unsigned int diff0, diff1, diff2;
+ unsigned int bit, byte;
+
+ diff0 = read_ecc[0] ^ calc_ecc[0];
+ diff1 = read_ecc[1] ^ calc_ecc[1];
+ diff2 = read_ecc[2] ^ calc_ecc[2];
+
+ if (diff0 == 0 && diff1 == 0 && diff2 == 0)
+ return 0; /* ECC is ok */
+
+ /* sometimes people do not think about using the ECC, so check
+ * to see if we have an 0xff,0xff,0xff read ECC and then ignore
+ * the error, on the assumption that this is an un-eccd page.
+ */
+ if (read_ecc[0] == 0xff && read_ecc[1] == 0xff && read_ecc[2] == 0xff)
+ return 0;
+
+ /* Can we correct this ECC (ie, one row and column change).
+ * Note, this is similar to the 256 error code on smartmedia */
+
+ if (((diff0 ^ (diff0 >> 1)) & 0x55) == 0x55 &&
+ ((diff1 ^ (diff1 >> 1)) & 0x55) == 0x55 &&
+ ((diff2 ^ (diff2 >> 1)) & 0x55) == 0x55) {
+ /* calculate the bit position of the error */
+
+ bit = ((diff2 >> 3) & 1) |
+ ((diff2 >> 4) & 2) |
+ ((diff2 >> 5) & 4);
+
+ /* calculate the byte position of the error */
+
+ byte = ((diff2 << 7) & 0x100) |
+ ((diff1 << 0) & 0x80) |
+ ((diff1 << 1) & 0x40) |
+ ((diff1 << 2) & 0x20) |
+ ((diff1 << 3) & 0x10) |
+ ((diff0 >> 4) & 0x08) |
+ ((diff0 >> 3) & 0x04) |
+ ((diff0 >> 2) & 0x02) |
+ ((diff0 >> 1) & 0x01);
+
+ dat[byte] ^= (1 << bit);
+ return 1;
+ }
+
+ /* if there is only one bit difference in the ECC, then
+ * one of only a row or column parity has changed, which
+ * means the error is most probably in the ECC itself */
+
+ diff0 |= (diff1 << 8);
+ diff0 |= (diff2 << 16);
+
+ if ((diff0 & ~(1<<fls(diff0))) == 0)
+ return 1;
+
+ return -1;
+}
+
+static void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct s3c24x0_nand_host *host = nand_chip->priv;
+
+#ifdef CONFIG_CPU_S3C2410
+ writel(readl(host->base + NFCONF) | NFCONF_INITECC , host->base + NFCONF);
+#endif
+#ifdef CONFIG_CPU_S3C2440
+ writel(readl(host->base + NFCONT) | NFCONT_INITECC , host->base + NFCONT);
+#endif
+}
+
+static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat, uint8_t *ecc_code)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct s3c24x0_nand_host *host = nand_chip->priv;
+
+#ifdef CONFIG_CPU_S3C2410
+ ecc_code[0] = readb(host->base + NFECC);
+ ecc_code[1] = readb(host->base + NFECC + 1);
+ ecc_code[2] = readb(host->base + NFECC + 2);
+#endif
+#ifdef CONFIG_CPU_S3C2440
+ unsigned long ecc = readl(host->base + NFECC);
+
+ ecc_code[0] = ecc;
+ ecc_code[1] = ecc >> 8;
+ ecc_code[2] = ecc >> 16;
+#endif
+ return 0;
+}
+
+static void s3c24x0_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct s3c24x0_nand_host *host = nand_chip->priv;
+
+ if (chip == -1)
+ disable_cs(host->base);
+ else
+ enable_cs(host->base);
+}
+
+static int s3c24x0_nand_devready(struct mtd_info *mtd)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct s3c24x0_nand_host *host = nand_chip->priv;
+
+ return readw(host->base + NFSTAT) & NFSTAT_BUSY;
+}
+
+static void s3c24x0_nand_hwcontrol(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct s3c24x0_nand_host *host = nand_chip->priv;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+ /*
+ * If the CLE should be active, this call is a NAND command
+ */
+ if (ctrl & NAND_CLE)
+ send_cmd(host->base, cmd);
+ /*
+ * If the ALE should be active, this call is a NAND address
+ */
+ if (ctrl & NAND_ALE)
+ send_addr(host->base, cmd);
+}
+
+static int s3c24x0_nand_inithw(struct s3c24x0_nand_host *host)
+{
+ struct s3c_nand_platform_data *pdata = host->dev->platform_data;
+ uint32_t tmp;
+
+ /* reset the NAND controller */
+ disable_nand_controller(host->base);
+
+ if (pdata != NULL)
+ tmp = pdata->nand_timing;
+ else
+ /* else slowest possible timing */
+ tmp = CALC_NFCONF_TIMING(4, 8, 8);
+
+ /* reenable the NAND controller */
+ enable_nand_controller(host->base, tmp);
+
+ return 0;
+}
+
+static int s3c24x0_nand_probe(struct device_d *dev)
+{
+ struct nand_chip *chip;
+ struct s3c_nand_platform_data *pdata = dev->platform_data;
+ struct mtd_info *mtd;
+ struct s3c24x0_nand_host *host;
+ int ret;
+
+ /* Allocate memory for MTD device structure and private data */
+ host = kzalloc(sizeof(struct s3c24x0_nand_host), GFP_KERNEL);
+ if (!host)
+ return -ENOMEM;
+
+ host->dev = dev;
+ host->base = dev_request_mem_region(dev, 0);
+
+ /* structures must be linked */
+ chip = &host->nand;
+ mtd = &host->mtd;
+ mtd->priv = chip;
+
+ /* init the default settings */
+
+ /* 50 us command delay time */
+ chip->chip_delay = 50;
+ chip->priv = host;
+
+ chip->IO_ADDR_R = chip->IO_ADDR_W = host->base + NFDATA;
+
+#ifdef CONFIG_CPU_S3C2440
+ chip->read_buf = s3c2440_nand_read_buf;
+ chip->write_buf = s3c2440_nand_write_buf;
+#endif
+ chip->cmd_ctrl = s3c24x0_nand_hwcontrol;
+ chip->dev_ready = s3c24x0_nand_devready;
+ chip->select_chip = s3c24x0_nand_select_chip;
+
+ /* we are using the hardware ECC feature of this device */
+ chip->ecc.calculate = s3c2410_nand_calculate_ecc;
+ chip->ecc.correct = s3c2410_nand_correct_data;
+ chip->ecc.hwctl = s3c2410_nand_enable_hwecc;
+
+ /*
+ * Setup ECC handling in accordance to the kernel
+ * - 1 times 512 bytes with 24 bit ECC for small page
+ * - 8 times 256 bytes with 24 bit ECC each for large page
+ */
+ chip->ecc.mode = NAND_ECC_HW;
+ chip->ecc.bytes = 3; /* always 24 bit ECC per turn */
+#ifdef CONFIG_CPU_S3C2440
+ if (readl(host->base) & 0x8) {
+ /* large page (2048 bytes per page) */
+ chip->ecc.size = 256;
+ } else
+#endif
+ {
+ /* small page (512 bytes per page) */
+ chip->ecc.size = 512;
+ chip->ecc.layout = &nand_hw_eccoob;
+ }
+
+ if (pdata->flash_bbt) {
+ /* use a flash based bbt */
+ chip->options |= NAND_USE_FLASH_BBT;
+ }
+
+ ret = s3c24x0_nand_inithw(host);
+ if (ret != 0)
+ goto on_error;
+
+ /* Scan to find existence of the device */
+ ret = nand_scan(mtd, 1);
+ if (ret != 0) {
+ ret = -ENXIO;
+ goto on_error;
+ }
+
+ return add_mtd_device(mtd, "nand");
+
+on_error:
+ free(host);
+ return ret;
+}
+
+static struct driver_d s3c24x0_nand_driver = {
+ .name = "s3c24x0_nand",
+ .probe = s3c24x0_nand_probe,
+};
+
+#ifdef CONFIG_S3C_NAND_BOOT
+
+static void __nand_boot_init wait_for_completion(void __iomem *host)
+{
+ while (!(readw(host + NFSTAT) & NFSTAT_BUSY))
+ ;
+}
+
+/**
+ * Convert a page offset into a page address for the NAND
+ * @param host Where to write the address to
+ * @param offs Page's offset in the NAND
+ * @param ps Page size (512 or 2048)
+ * @param c Address cycle count (3, 4 or 5)
+ *
+ * Uses the offset of the page to generate an page address into the NAND. This
+ * differs when using a 512 byte or 2048 bytes per page NAND.
+ * The collumn part of the page address to be generated is always forced to '0'.
+ */
+static void __nand_boot_init nfc_addr(void __iomem *host, uint32_t offs,
+ int ps, int c)
+{
+ send_addr(host, 0); /* collumn part 1 */
+
+ if (ps == 512) {
+ send_addr(host, offs >> 9);
+ send_addr(host, offs >> 17);
+ if (c > 3)
+ send_addr(host, offs >> 25);
+ } else {
+ send_addr(host, 0); /* collumn part 2 */
+ send_addr(host, offs >> 11);
+ send_addr(host, offs >> 19);
+ if (c > 4)
+ send_addr(host, offs >> 27);
+ send_cmd(host, NAND_CMD_READSTART);
+ }
+}
+
+/**
+ * Load a sequential count of pages from the NAND into memory
+ * @param[out] dest Pointer to target area (in SDRAM)
+ * @param[in] size Bytes to read from NAND device
+ * @param[in] page Start page to read from
+ *
+ * This function must be located in the first 4kiB of the barebox image
+ * (guess why).
+ */
+void __nand_boot_init s3c_nand_load_image(void *dest, int size, int page)
+{
+ void __iomem *host = (void __iomem *)S3C24X0_NAND_BASE;
+ unsigned pagesize;
+ int i, cycle;
+
+ /*
+ * Reenable the NFC and use the default (but slow) access
+ * timing or the board specific setting if provided.
+ */
+ enable_nand_controller(host, BOARD_DEFAULT_NAND_TIMING);
+
+ /* use the current NAND hardware configuration */
+ switch (readl(S3C24X0_NAND_BASE) & 0xf) {
+ case 0x6: /* 8 bit, 4 addr cycles, 512 bpp, normal NAND */
+ pagesize = 512;
+ cycle = 4;
+ break;
+ case 0xc: /* 8 bit, 4 addr cycles, 2048 bpp, advanced NAND */
+ pagesize = 2048;
+ cycle = 4;
+ break;
+ case 0xe: /* 8 bit, 5 addr cycles, 2048 bpp, advanced NAND */
+ pagesize = 2048;
+ cycle = 5;
+ break;
+ default:
+ /* we cannot output an error message here :-( */
+ disable_nand_controller(host);
+ return;
+ }
+
+ enable_cs(host);
+
+ /* Reset the NAND device */
+ send_cmd(host, NAND_CMD_RESET);
+ wait_for_completion(host);
+ disable_cs(host);
+
+ do {
+ enable_cs(host);
+ send_cmd(host, NAND_CMD_READ0);
+ nfc_addr(host, page * pagesize, pagesize, cycle);
+ wait_for_completion(host);
+ /* copy one page (do *not* use readsb() here!)*/
+ for (i = 0; i < pagesize; i++)
+ writeb(readb(host + NFDATA), (void __iomem *)(dest + i));
+ disable_cs(host);
+
+ page++;
+ dest += pagesize;
+ size -= pagesize;
+ } while (size >= 0);
+
+ /* disable the controller again */
+ disable_nand_controller(host);
+}
+
+#ifdef CONFIG_NAND_S3C_BOOT_DEBUG
+#include <command.h>
+
+static int do_nand_boot_test(int argc, char *argv[])
+{
+ void *dest;
+ int size;
+
+ if (argc < 3)
+ return COMMAND_ERROR_USAGE;
+
+ dest = (void *)strtoul_suffix(argv[1], NULL, 0);
+ size = strtoul_suffix(argv[2], NULL, 0);
+
+ s3c_nand_load_image(dest, size, 0);
+
+ /* re-enable the controller again, as this was a test only */
+ enable_nand_controller((void *)S3C24X0_NAND_BASE,
+ BOARD_DEFAULT_NAND_TIMING);
+
+ return 0;
+}
+
+static const __maybe_unused char cmd_nand_boot_test_help[] =
+"Usage: nand_boot_test <dest> <size>\n";
+
+BAREBOX_CMD_START(nand_boot_test)
+ .cmd = do_nand_boot_test,
+ .usage = "load an image from NAND",
+ BAREBOX_CMD_HELP(cmd_nand_boot_test_help)
+BAREBOX_CMD_END
+#endif
+
+#endif /* CONFIG_S3C_NAND_BOOT */
+
+/*
+ * Main initialization routine
+ * @return 0 if successful; non-zero otherwise
+ */
+static int __init s3c24x0_nand_init(void)
+{
+ return register_driver(&s3c24x0_nand_driver);
+}
+
+device_initcall(s3c24x0_nand_init);
+
+/**
+ * @file
+ * @brief Support for various kinds of NAND devices
+ *
+ * ECC handling in this driver (in accordance to the current 2.6.38 kernel):
+ * - for small page NANDs it generates 3 ECC bytes out of 512 data bytes
+ * - for large page NANDs it generates 24 ECC bytes out of 2048 data bytes
+ *
+ * As small page NANDs are using 48 bits ECC per default, this driver uses a
+ * local OOB layout description, to shrink it down to 24 bits. This is a bad
+ * idea, but we cannot change it here, as the kernel is using this layout.
+ *
+ * For large page NANDs this driver uses the default layout, as the kernel does.
+ */
diff --git a/drivers/mtd/nand/nand_s3c24xx.c b/drivers/mtd/nand/nand_s3c24xx.c
deleted file mode 100644
index dbf2e14..0000000
--- a/drivers/mtd/nand/nand_s3c24xx.c
+++ /dev/null
@@ -1,665 +0,0 @@
-/* linux/drivers/mtd/nand/s3c2410.c
- *
- * Copyright (C) 2009 Juergen Beisert, Pengutronix
- *
- * Copyright © 2004-2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C2410 NAND driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <config.h>
-#include <common.h>
-#include <driver.h>
-#include <malloc.h>
-#include <init.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <mach/s3c-generic.h>
-#include <mach/s3c-iomap.h>
-#include <mach/s3c24xx-nand.h>
-#include <io.h>
-#include <asm-generic/errno.h>
-
-#ifdef CONFIG_S3C24XX_NAND_BOOT
-# define __nand_boot_init __bare_init
-# ifndef BOARD_DEFAULT_NAND_TIMING
-# define BOARD_DEFAULT_NAND_TIMING 0x0737
-# endif
-#else
-# define __nand_boot_init
-#endif
-
-/**
- * Define this symbol for testing purpose. It will add a command to read an
- * image from the NAND like it the boot strap code will do.
- */
-#define CONFIG_NAND_S3C24XX_BOOT_DEBUG
-
-/* NAND controller's register */
-
-#define NFCONF 0x00
-
-#ifdef CONFIG_CPU_S3C2410
-
-#define NFCMD 0x04
-#define NFADDR 0x08
-#define NFDATA 0x0c
-#define NFSTAT 0x10
-#define NFECC 0x14
-
-/* S3C2410 specific bits */
-#define NFSTAT_BUSY (1)
-#define NFCONF_nFCE (1 << 11)
-#define NFCONF_INITECC (1 << 12)
-#define NFCONF_EN (1 << 15)
-
-#endif /* CONFIG_CPU_S3C2410 */
-
-#ifdef CONFIG_CPU_S3C2440
-
-#define NFCONT 0x04
-#define NFCMD 0x08
-#define NFADDR 0x0C
-#define NFDATA 0x10
-#define NFSTAT 0x20
-#define NFECC 0x2C
-
-/* S3C2440 specific bits */
-#define NFSTAT_BUSY (1)
-#define NFCONT_nFCE (1 << 1)
-#define NFCONT_INITECC (1 << 4)
-#define NFCONT_EN (1)
-
-#endif /* CONFIG_CPU_S3C2440 */
-
-
-struct s3c24x0_nand_host {
- struct mtd_info mtd;
- struct nand_chip nand;
- struct mtd_partition *parts;
- struct device_d *dev;
-
- void __iomem *base;
-};
-
-/**
- * oob placement block for use with hardware ecc generation on small page
- */
-static struct nand_ecclayout nand_hw_eccoob = {
- .eccbytes = 3,
- .eccpos = { 0, 1, 2},
- .oobfree = {
- {
- .offset = 8,
- .length = 8
- }
- }
-};
-
-/* - Functions shared between the boot strap code and the regular driver - */
-
-/**
- * Issue the specified command to the NAND device
- * @param[in] host Base address of the NAND controller
- * @param[in] cmd Command for NAND flash
- */
-static void __nand_boot_init send_cmd(void __iomem *host, uint8_t cmd)
-{
- writeb(cmd, host + NFCMD);
-}
-
-/**
- * Issue the specified address to the NAND device
- * @param[in] host Base address of the NAND controller
- * @param[in] addr Address for the NAND flash
- */
-static void __nand_boot_init send_addr(void __iomem *host, uint8_t addr)
-{
- writeb(addr, host + NFADDR);
-}
-
-/**
- * Enable the NAND flash access
- * @param[in] host Base address of the NAND controller
- */
-static void __nand_boot_init enable_cs(void __iomem *host)
-{
-#ifdef CONFIG_CPU_S3C2410
- writew(readw(host + NFCONF) & ~NFCONF_nFCE, host + NFCONF);
-#endif
-#ifdef CONFIG_CPU_S3C2440
- writew(readw(host + NFCONT) & ~NFCONT_nFCE, host + NFCONT);
-#endif
-}
-
-/**
- * Disable the NAND flash access
- * @param[in] host Base address of the NAND controller
- */
-static void __nand_boot_init disable_cs(void __iomem *host)
-{
-#ifdef CONFIG_CPU_S3C2410
- writew(readw(host + NFCONF) | NFCONF_nFCE, host + NFCONF);
-#endif
-#ifdef CONFIG_CPU_S3C2440
- writew(readw(host + NFCONT) | NFCONT_nFCE, host + NFCONT);
-#endif
-}
-
-/**
- * Enable the NAND flash controller
- * @param[in] host Base address of the NAND controller
- * @param[in] timing Timing to access the NAND memory
- */
-static void __nand_boot_init enable_nand_controller(void __iomem *host, uint32_t timing)
-{
-#ifdef CONFIG_CPU_S3C2410
- writew(timing + NFCONF_EN + NFCONF_nFCE, host + NFCONF);
-#endif
-#ifdef CONFIG_CPU_S3C2440
- writew(NFCONT_EN + NFCONT_nFCE, host + NFCONT);
- writew(timing, host + NFCONF);
-#endif
-}
-
-/**
- * Diable the NAND flash controller
- * @param[in] host Base address of the NAND controller
- */
-static void __nand_boot_init disable_nand_controller(void __iomem *host)
-{
-#ifdef CONFIG_CPU_S3C2410
- writew(NFCONF_nFCE, host + NFCONF);
-#endif
-#ifdef CONFIG_CPU_S3C2440
- writew(NFCONT_nFCE, host + NFCONT);
-#endif
-}
-
-/* ----------------------------------------------------------------------- */
-
-#ifdef CONFIG_CPU_S3C2440
-/**
- * Read one block of data from the NAND port
- * @param[in] mtd Instance data
- * @param[out] buf buffer to write data to
- * @param[in] len byte count
- *
- * This is a special block read variant for the S3C2440 CPU.
- */
-static void s3c2440_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
-{
- struct nand_chip *nand_chip = mtd->priv;
- struct s3c24x0_nand_host *host = nand_chip->priv;
-
- readsl(host->base + NFDATA, buf, len >> 2);
-
- /* cleanup any fractional read */
- if (len & 3) {
- buf += len & ~3;
-
- for (; len & 3; len--)
- *buf++ = readb(host->base + NFDATA);
- }
-}
-
-/**
- * Write one block of data to the NAND port
- * @param[in] mtd Instance data
- * @param[out] buf buffer to read data from
- * @param[in] len byte count
- *
- * This is a special block write variant for the S3C2440 CPU.
- */
-static void s3c2440_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf,
- int len)
-{
- struct nand_chip *nand_chip = mtd->priv;
- struct s3c24x0_nand_host *host = nand_chip->priv;
-
- writesl(host->base + NFDATA, buf, len >> 2);
-
- /* cleanup any fractional write */
- if (len & 3) {
- buf += len & ~3;
-
- for (; len & 3; len--, buf++)
- writeb(*buf, host->base + NFDATA);
- }
-}
-#endif
-
-/**
- * Check the ECC and try to repair the data if possible
- * @param[in] mtd_info Not used
- * @param[inout] dat Pointer to the data buffer that might contain a bit error
- * @param[in] read_ecc ECC data from the OOB space
- * @param[in] calc_ecc ECC data calculated from the data
- * @return 0 no error, 1 repaired error, -1 no way...
- *
- * @note: This routine works always on a 24 bit ECC
- */
-static int s3c2410_nand_correct_data(struct mtd_info *mtd, uint8_t *dat,
- uint8_t *read_ecc, uint8_t *calc_ecc)
-{
- unsigned int diff0, diff1, diff2;
- unsigned int bit, byte;
-
- diff0 = read_ecc[0] ^ calc_ecc[0];
- diff1 = read_ecc[1] ^ calc_ecc[1];
- diff2 = read_ecc[2] ^ calc_ecc[2];
-
- if (diff0 == 0 && diff1 == 0 && diff2 == 0)
- return 0; /* ECC is ok */
-
- /* sometimes people do not think about using the ECC, so check
- * to see if we have an 0xff,0xff,0xff read ECC and then ignore
- * the error, on the assumption that this is an un-eccd page.
- */
- if (read_ecc[0] == 0xff && read_ecc[1] == 0xff && read_ecc[2] == 0xff)
- return 0;
-
- /* Can we correct this ECC (ie, one row and column change).
- * Note, this is similar to the 256 error code on smartmedia */
-
- if (((diff0 ^ (diff0 >> 1)) & 0x55) == 0x55 &&
- ((diff1 ^ (diff1 >> 1)) & 0x55) == 0x55 &&
- ((diff2 ^ (diff2 >> 1)) & 0x55) == 0x55) {
- /* calculate the bit position of the error */
-
- bit = ((diff2 >> 3) & 1) |
- ((diff2 >> 4) & 2) |
- ((diff2 >> 5) & 4);
-
- /* calculate the byte position of the error */
-
- byte = ((diff2 << 7) & 0x100) |
- ((diff1 << 0) & 0x80) |
- ((diff1 << 1) & 0x40) |
- ((diff1 << 2) & 0x20) |
- ((diff1 << 3) & 0x10) |
- ((diff0 >> 4) & 0x08) |
- ((diff0 >> 3) & 0x04) |
- ((diff0 >> 2) & 0x02) |
- ((diff0 >> 1) & 0x01);
-
- dat[byte] ^= (1 << bit);
- return 1;
- }
-
- /* if there is only one bit difference in the ECC, then
- * one of only a row or column parity has changed, which
- * means the error is most probably in the ECC itself */
-
- diff0 |= (diff1 << 8);
- diff0 |= (diff2 << 16);
-
- if ((diff0 & ~(1<<fls(diff0))) == 0)
- return 1;
-
- return -1;
-}
-
-static void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
-{
- struct nand_chip *nand_chip = mtd->priv;
- struct s3c24x0_nand_host *host = nand_chip->priv;
-
-#ifdef CONFIG_CPU_S3C2410
- writel(readl(host->base + NFCONF) | NFCONF_INITECC , host->base + NFCONF);
-#endif
-#ifdef CONFIG_CPU_S3C2440
- writel(readl(host->base + NFCONT) | NFCONT_INITECC , host->base + NFCONT);
-#endif
-}
-
-static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat, uint8_t *ecc_code)
-{
- struct nand_chip *nand_chip = mtd->priv;
- struct s3c24x0_nand_host *host = nand_chip->priv;
-
-#ifdef CONFIG_CPU_S3C2410
- ecc_code[0] = readb(host->base + NFECC);
- ecc_code[1] = readb(host->base + NFECC + 1);
- ecc_code[2] = readb(host->base + NFECC + 2);
-#endif
-#ifdef CONFIG_CPU_S3C2440
- unsigned long ecc = readl(host->base + NFECC);
-
- ecc_code[0] = ecc;
- ecc_code[1] = ecc >> 8;
- ecc_code[2] = ecc >> 16;
-#endif
- return 0;
-}
-
-static void s3c24x0_nand_select_chip(struct mtd_info *mtd, int chip)
-{
- struct nand_chip *nand_chip = mtd->priv;
- struct s3c24x0_nand_host *host = nand_chip->priv;
-
- if (chip == -1)
- disable_cs(host->base);
- else
- enable_cs(host->base);
-}
-
-static int s3c24x0_nand_devready(struct mtd_info *mtd)
-{
- struct nand_chip *nand_chip = mtd->priv;
- struct s3c24x0_nand_host *host = nand_chip->priv;
-
- return readw(host->base + NFSTAT) & NFSTAT_BUSY;
-}
-
-static void s3c24x0_nand_hwcontrol(struct mtd_info *mtd, int cmd,
- unsigned int ctrl)
-{
- struct nand_chip *nand_chip = mtd->priv;
- struct s3c24x0_nand_host *host = nand_chip->priv;
-
- if (cmd == NAND_CMD_NONE)
- return;
- /*
- * If the CLE should be active, this call is a NAND command
- */
- if (ctrl & NAND_CLE)
- send_cmd(host->base, cmd);
- /*
- * If the ALE should be active, this call is a NAND address
- */
- if (ctrl & NAND_ALE)
- send_addr(host->base, cmd);
-}
-
-static int s3c24x0_nand_inithw(struct s3c24x0_nand_host *host)
-{
- struct s3c24x0_nand_platform_data *pdata = host->dev->platform_data;
- uint32_t tmp;
-
- /* reset the NAND controller */
- disable_nand_controller(host->base);
-
- if (pdata != NULL)
- tmp = pdata->nand_timing;
- else
- /* else slowest possible timing */
- tmp = CALC_NFCONF_TIMING(4, 8, 8);
-
- /* reenable the NAND controller */
- enable_nand_controller(host->base, tmp);
-
- return 0;
-}
-
-static int s3c24x0_nand_probe(struct device_d *dev)
-{
- struct nand_chip *chip;
- struct s3c24x0_nand_platform_data *pdata = dev->platform_data;
- struct mtd_info *mtd;
- struct s3c24x0_nand_host *host;
- int ret;
-
- /* Allocate memory for MTD device structure and private data */
- host = kzalloc(sizeof(struct s3c24x0_nand_host), GFP_KERNEL);
- if (!host)
- return -ENOMEM;
-
- host->dev = dev;
- host->base = dev_request_mem_region(dev, 0);
-
- /* structures must be linked */
- chip = &host->nand;
- mtd = &host->mtd;
- mtd->priv = chip;
-
- /* init the default settings */
-
- /* 50 us command delay time */
- chip->chip_delay = 50;
- chip->priv = host;
-
- chip->IO_ADDR_R = chip->IO_ADDR_W = host->base + NFDATA;
-
-#ifdef CONFIG_CPU_S3C2440
- chip->read_buf = s3c2440_nand_read_buf;
- chip->write_buf = s3c2440_nand_write_buf;
-#endif
- chip->cmd_ctrl = s3c24x0_nand_hwcontrol;
- chip->dev_ready = s3c24x0_nand_devready;
- chip->select_chip = s3c24x0_nand_select_chip;
-
- /* we are using the hardware ECC feature of this device */
- chip->ecc.calculate = s3c2410_nand_calculate_ecc;
- chip->ecc.correct = s3c2410_nand_correct_data;
- chip->ecc.hwctl = s3c2410_nand_enable_hwecc;
-
- /*
- * Setup ECC handling in accordance to the kernel
- * - 1 times 512 bytes with 24 bit ECC for small page
- * - 8 times 256 bytes with 24 bit ECC each for large page
- */
- chip->ecc.mode = NAND_ECC_HW;
- chip->ecc.bytes = 3; /* always 24 bit ECC per turn */
-#ifdef CONFIG_CPU_S3C2440
- if (readl(host->base) & 0x8) {
- /* large page (2048 bytes per page) */
- chip->ecc.size = 256;
- } else
-#endif
- {
- /* small page (512 bytes per page) */
- chip->ecc.size = 512;
- chip->ecc.layout = &nand_hw_eccoob;
- }
-
- if (pdata->flash_bbt) {
- /* use a flash based bbt */
- chip->options |= NAND_USE_FLASH_BBT;
- }
-
- ret = s3c24x0_nand_inithw(host);
- if (ret != 0)
- goto on_error;
-
- /* Scan to find existence of the device */
- ret = nand_scan(mtd, 1);
- if (ret != 0) {
- ret = -ENXIO;
- goto on_error;
- }
-
- return add_mtd_device(mtd, "nand");
-
-on_error:
- free(host);
- return ret;
-}
-
-static struct driver_d s3c24x0_nand_driver = {
- .name = "s3c24x0_nand",
- .probe = s3c24x0_nand_probe,
-};
-
-#ifdef CONFIG_S3C24XX_NAND_BOOT
-
-static void __nand_boot_init wait_for_completion(void __iomem *host)
-{
- while (!(readw(host + NFSTAT) & NFSTAT_BUSY))
- ;
-}
-
-/**
- * Convert a page offset into a page address for the NAND
- * @param host Where to write the address to
- * @param offs Page's offset in the NAND
- * @param ps Page size (512 or 2048)
- * @param c Address cycle count (3, 4 or 5)
- *
- * Uses the offset of the page to generate an page address into the NAND. This
- * differs when using a 512 byte or 2048 bytes per page NAND.
- * The collumn part of the page address to be generated is always forced to '0'.
- */
-static void __nand_boot_init nfc_addr(void __iomem *host, uint32_t offs,
- int ps, int c)
-{
- send_addr(host, 0); /* collumn part 1 */
-
- if (ps == 512) {
- send_addr(host, offs >> 9);
- send_addr(host, offs >> 17);
- if (c > 3)
- send_addr(host, offs >> 25);
- } else {
- send_addr(host, 0); /* collumn part 2 */
- send_addr(host, offs >> 11);
- send_addr(host, offs >> 19);
- if (c > 4)
- send_addr(host, offs >> 27);
- send_cmd(host, NAND_CMD_READSTART);
- }
-}
-
-/**
- * Load a sequential count of pages from the NAND into memory
- * @param[out] dest Pointer to target area (in SDRAM)
- * @param[in] size Bytes to read from NAND device
- * @param[in] page Start page to read from
- *
- * This function must be located in the first 4kiB of the barebox image
- * (guess why).
- */
-void __nand_boot_init s3c24x0_nand_load_image(void *dest, int size, int page)
-{
- void __iomem *host = (void __iomem *)S3C24X0_NAND_BASE;
- unsigned pagesize;
- int i, cycle;
-
- /*
- * Reenable the NFC and use the default (but slow) access
- * timing or the board specific setting if provided.
- */
- enable_nand_controller(host, BOARD_DEFAULT_NAND_TIMING);
-
- /* use the current NAND hardware configuration */
- switch (readl(S3C24X0_NAND_BASE) & 0xf) {
- case 0x6: /* 8 bit, 4 addr cycles, 512 bpp, normal NAND */
- pagesize = 512;
- cycle = 4;
- break;
- case 0xc: /* 8 bit, 4 addr cycles, 2048 bpp, advanced NAND */
- pagesize = 2048;
- cycle = 4;
- break;
- case 0xe: /* 8 bit, 5 addr cycles, 2048 bpp, advanced NAND */
- pagesize = 2048;
- cycle = 5;
- break;
- default:
- /* we cannot output an error message here :-( */
- disable_nand_controller(host);
- return;
- }
-
- enable_cs(host);
-
- /* Reset the NAND device */
- send_cmd(host, NAND_CMD_RESET);
- wait_for_completion(host);
- disable_cs(host);
-
- do {
- enable_cs(host);
- send_cmd(host, NAND_CMD_READ0);
- nfc_addr(host, page * pagesize, pagesize, cycle);
- wait_for_completion(host);
- /* copy one page (do *not* use readsb() here!)*/
- for (i = 0; i < pagesize; i++)
- writeb(readb(host + NFDATA), (void __iomem *)(dest + i));
- disable_cs(host);
-
- page++;
- dest += pagesize;
- size -= pagesize;
- } while (size >= 0);
-
- /* disable the controller again */
- disable_nand_controller(host);
-}
-
-#ifdef CONFIG_NAND_S3C24XX_BOOT_DEBUG
-#include <command.h>
-
-static int do_nand_boot_test(int argc, char *argv[])
-{
- void *dest;
- int size;
-
- if (argc < 3)
- return COMMAND_ERROR_USAGE;
-
- dest = (void *)strtoul_suffix(argv[1], NULL, 0);
- size = strtoul_suffix(argv[2], NULL, 0);
-
- s3c24x0_nand_load_image(dest, size, 0);
-
- /* re-enable the controller again, as this was a test only */
- enable_nand_controller((void *)S3C24X0_NAND_BASE,
- BOARD_DEFAULT_NAND_TIMING);
-
- return 0;
-}
-
-static const __maybe_unused char cmd_nand_boot_test_help[] =
-"Usage: nand_boot_test <dest> <size>\n";
-
-BAREBOX_CMD_START(nand_boot_test)
- .cmd = do_nand_boot_test,
- .usage = "load an image from NAND",
- BAREBOX_CMD_HELP(cmd_nand_boot_test_help)
-BAREBOX_CMD_END
-#endif
-
-#endif /* CONFIG_S3C24XX_NAND_BOOT */
-
-/*
- * Main initialization routine
- * @return 0 if successful; non-zero otherwise
- */
-static int __init s3c24x0_nand_init(void)
-{
- return register_driver(&s3c24x0_nand_driver);
-}
-
-device_initcall(s3c24x0_nand_init);
-
-/**
- * @file
- * @brief Support for various kinds of NAND devices
- *
- * ECC handling in this driver (in accordance to the current 2.6.38 kernel):
- * - for small page NANDs it generates 3 ECC bytes out of 512 data bytes
- * - for large page NANDs it generates 24 ECC bytes out of 2048 data bytes
- *
- * As small page NANDs are using 48 bits ECC per default, this driver uses a
- * local OOB layout description, to shrink it down to 24 bits. This is a bad
- * idea, but we cannot change it here, as the kernel is using this layout.
- *
- * For large page NANDs this driver uses the default layout, as the kernel does.
- */
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 186b596..a9383da 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -80,7 +80,7 @@ config DRIVER_SERIAL_PL010
config DRIVER_SERIAL_S3C
bool "Samsung S3C serial driver"
- depends on ARCH_S3C24xx
+ depends on ARCH_SAMSUNG
default y
help
Say Y here if you want to use the CONS on a Samsung S3C CPU
--
1.7.10
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 3/4] Minimal S5PV210 + Tiny210 support (2nd stage only)
2012-05-03 13:14 [PATCH 0/4] Support Samsung S5PV210 CPU Alexey Galakhov
2012-05-03 13:14 ` [PATCH 1/4] Support most Samsung SoCs in S3C serial driver Alexey Galakhov
2012-05-03 13:14 ` [PATCH 2/4] Fine split S3C arch dependencies from generic code Alexey Galakhov
@ 2012-05-03 13:14 ` Alexey Galakhov
2012-05-03 17:49 ` Juergen Beisert
2012-05-03 13:14 ` [PATCH 4/4] S5PV210 iROM magic boot code Alexey Galakhov
3 siblings, 1 reply; 19+ messages in thread
From: Alexey Galakhov @ 2012-05-03 13:14 UTC (permalink / raw)
To: barebox; +Cc: Alexey Galakhov
Signed-off-by: Alexey Galakhov <agalakhov@gmail.com>
---
arch/arm/Kconfig | 6 +
arch/arm/Makefile | 1 +
arch/arm/boards/tiny210/Makefile | 1 +
arch/arm/boards/tiny210/config.h | 1 +
arch/arm/boards/tiny210/lowlevel.c | 31 +
arch/arm/boards/tiny210/tiny210.c | 113 +++
arch/arm/mach-samsung/Kconfig | 24 +
arch/arm/mach-samsung/Makefile | 1 +
arch/arm/mach-samsung/clocks-s5pcxx.c | 98 +++
arch/arm/mach-samsung/gpio-s5pcxx.c | 123 +++
arch/arm/mach-samsung/include/mach/clocks-s5pcxx.h | 55 ++
arch/arm/mach-samsung/include/mach/gpio.h | 3 +
arch/arm/mach-samsung/include/mach/iomap-s5pcxx.h | 49 ++
arch/arm/mach-samsung/include/mach/iomux-s5pcxx.h | 798 ++++++++++++++++++++
arch/arm/mach-samsung/include/mach/s3c-clocks.h | 3 +
arch/arm/mach-samsung/include/mach/s3c-iomap.h | 3 +
16 files changed, 1310 insertions(+)
create mode 100644 arch/arm/boards/tiny210/Makefile
create mode 100644 arch/arm/boards/tiny210/config.h
create mode 100644 arch/arm/boards/tiny210/lowlevel.c
create mode 100644 arch/arm/boards/tiny210/tiny210.c
create mode 100644 arch/arm/mach-samsung/clocks-s5pcxx.c
create mode 100644 arch/arm/mach-samsung/gpio-s5pcxx.c
create mode 100644 arch/arm/mach-samsung/include/mach/clocks-s5pcxx.h
create mode 100644 arch/arm/mach-samsung/include/mach/iomap-s5pcxx.h
create mode 100644 arch/arm/mach-samsung/include/mach/iomux-s5pcxx.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8a4e1a2..f465084 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -73,6 +73,12 @@ config ARCH_S3C24xx
select CPU_ARM920T
select GENERIC_GPIO
+config ARCH_S5PCxx
+ bool "Samsung S5PC110, S5PV210"
+ select ARCH_SAMSUNG
+ select CPU_V7
+ select GENERIC_GPIO
+
config ARCH_VERSATILE
bool "ARM Versatile boards (ARM926EJ-S)"
select CPU_ARM926T
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 5299486..482e77f 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -130,6 +130,7 @@ board-$(CONFIG_MACH_USB_A9G20) := usb-a926x
board-$(CONFIG_MACH_VERSATILEPB) := versatile
board-$(CONFIG_MACH_TX25) := karo-tx25
board-$(CONFIG_MACH_TQMA53) := tqma53
+board-$(CONFIG_MACH_TINY210) := tiny210
machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
diff --git a/arch/arm/boards/tiny210/Makefile b/arch/arm/boards/tiny210/Makefile
new file mode 100644
index 0000000..9c38e60
--- /dev/null
+++ b/arch/arm/boards/tiny210/Makefile
@@ -0,0 +1 @@
+obj-y += tiny210.o lowlevel.o
diff --git a/arch/arm/boards/tiny210/config.h b/arch/arm/boards/tiny210/config.h
new file mode 100644
index 0000000..ebf661e
--- /dev/null
+++ b/arch/arm/boards/tiny210/config.h
@@ -0,0 +1 @@
+#define S5PCXX_CLOCK_REFERENCE 24000000
diff --git a/arch/arm/boards/tiny210/lowlevel.c b/arch/arm/boards/tiny210/lowlevel.c
new file mode 100644
index 0000000..3615d8a
--- /dev/null
+++ b/arch/arm/boards/tiny210/lowlevel.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2012 Alexey Galakhov
+ *
+ * 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
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <config.h>
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <asm/barebox-arm.h>
+#include <mach/s3c-iomap.h>
+#include <mach/s3c-clocks.h>
+
+void __bare_init board_init_lowlevel(void)
+{
+}
diff --git a/arch/arm/boards/tiny210/tiny210.c b/arch/arm/boards/tiny210/tiny210.c
new file mode 100644
index 0000000..eb23196
--- /dev/null
+++ b/arch/arm/boards/tiny210/tiny210.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2012 Alexey Galakhov
+ * Based on Mini6410 code by Juergen Beisert
+ *
+ * Copyright (C) 2012 Juergen Beisert, Pengutronix
+ *
+ * In some ways inspired by code
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <sizes.h>
+#include <generated/mach-types.h>
+#include <dm9000.h>
+#include <gpio.h>
+#include <led.h>
+#include <io.h>
+#include <nand.h>
+#include <asm/armlinux.h>
+#include <mach/s3c-iomap.h>
+#include <mach/s3c-clocks.h>
+#include <mach/s3c-generic.h>
+
+
+static const unsigned pin_usage[] = {
+ /* TODO */
+};
+
+static struct gpio_led leds[] = {
+ {
+ .gpio = GPJ20,
+ .led = {
+ .name = "led1",
+ }
+ }, {
+ .gpio = GPJ21,
+ .led = {
+ .name = "led2",
+ }
+ }, {
+ .gpio = GPJ22,
+ .led = {
+ .name = "led3",
+ }
+ }, {
+ .gpio = GPJ23,
+ .led = {
+ .name = "led4",
+ }
+ }
+};
+
+static int tiny210_mem_init(void)
+{
+ arm_add_mem_device("ram0", S3C_SDRAM_BASE, (512 << 20));
+ return 0;
+}
+mem_initcall(tiny210_mem_init);
+
+static int tiny210_console_init(void)
+{
+ /*
+ * configure the UART1 right now, as barebox will
+ * start to send data immediately
+ */
+ s3c_gpio_mode(GPA00_RXD0 | ENABLE_PU);
+ s3c_gpio_mode(GPA01_TXD0);
+ s3c_gpio_mode(GPA02_NCTS0 | ENABLE_PU);
+ s3c_gpio_mode(GPA03_NRTS0);
+
+ add_generic_device("s3c_serial", -1, NULL,
+ S3C_UART1_BASE, S3C_UART1_SIZE,
+ IORESOURCE_MEM, NULL);
+ return 0;
+}
+console_initcall(tiny210_console_init);
+
+static int tiny210_devices_init(void)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(pin_usage); i++)
+ s3c_gpio_mode(pin_usage[i]);
+
+ for (i = 0; i < ARRAY_SIZE(leds); i++) {
+ leds[i].active_low = 1;
+ gpio_direction_output(leds[i].gpio, leds[i].active_low);
+ led_gpio_register(&leds[i]);
+ }
+
+ armlinux_set_bootparams((void*)S3C_SDRAM_BASE + 0x100);
+ armlinux_set_architecture(MACH_TYPE_MINI210);
+
+ return 0;
+}
+device_initcall(tiny210_devices_init);
diff --git a/arch/arm/mach-samsung/Kconfig b/arch/arm/mach-samsung/Kconfig
index 4d5f7c5..fcef677 100644
--- a/arch/arm/mach-samsung/Kconfig
+++ b/arch/arm/mach-samsung/Kconfig
@@ -13,6 +13,7 @@ config BOARDINFO
default "Mini 2440" if MACH_MINI2440
default "Digi A9M2440" if MACH_A9M2440
default "Digi A9M2410" if MACH_A9M2410
+ default "Tiny 210" if MACH_TINY210
if ARCH_S3C24xx
@@ -80,6 +81,29 @@ endmenu
endif
+if ARCH_S5PCxx
+
+config CPU_S5PC110
+ bool
+
+config CPU_S5PV210
+ bool
+
+choice
+
+ prompt "S5PCxx board type"
+
+config MACH_TINY210
+ bool "Tiny 210"
+ select CPU_S5PV210
+ select MACH_HAS_LOWLEVEL_INIT
+ select MACH_DO_LOWLEVEL_INIT
+
+endchoice
+
+endif
+
+
menu "S3C Features "
config S3C_LOWLEVEL_INIT
diff --git a/arch/arm/mach-samsung/Makefile b/arch/arm/mach-samsung/Makefile
index 8f032fb..66f3fd2 100644
--- a/arch/arm/mach-samsung/Makefile
+++ b/arch/arm/mach-samsung/Makefile
@@ -1,4 +1,5 @@
obj-y += s3c-timer.o generic.o
obj-lowlevel-$(CONFIG_ARCH_S3C24xx) += lowlevel-s3c24x0.o
obj-$(CONFIG_ARCH_S3C24xx) += gpio-s3c24x0.o clocks-s3c24x0.o mem-s3c24x0.o
+obj-$(CONFIG_ARCH_S5PCxx) += gpio-s5pcxx.o clocks-s5pcxx.o
obj-$(CONFIG_S3C_LOWLEVEL_INIT) += $(obj-lowlevel-y)
diff --git a/arch/arm/mach-samsung/clocks-s5pcxx.c b/arch/arm/mach-samsung/clocks-s5pcxx.c
new file mode 100644
index 0000000..1f4790b
--- /dev/null
+++ b/arch/arm/mach-samsung/clocks-s5pcxx.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2012 Alexey Galakhov
+ * Copyright (C) 2012 Juergen Beisert, Pengutronix
+ *
+ * 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.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <io.h>
+#include <mach/s3c-iomap.h>
+#include <mach/s3c-generic.h>
+#include <mach/s3c-clocks.h>
+
+static inline uint32_t clkdiv(uint32_t clk, unsigned bit, unsigned mask)
+{
+ uint32_t ratio = (readl(S5P_CLK_DIV0) >> bit) & mask;
+ return clk / (ratio + 1);
+}
+
+uint32_t s3c_get_mpllclk(void)
+{
+ uint32_t m, p, s;
+ uint32_t reg = readl(S5P_xPLL_CON + S5P_MPLL);
+ m = (reg >> 16) & 0x3ff;
+ p = (reg >> 8) & 0x3f;
+ s = (reg >> 0) & 0x7;
+ return m * ((S5PCXX_CLOCK_REFERENCE) / (p << s));
+}
+
+uint32_t s3c_get_apllclk(void)
+{
+ uint32_t m, p, s;
+ uint32_t reg = readl(S5P_xPLL_CON + S5P_APLL);
+ m = (reg >> 16) & 0x3ff;
+ p = (reg >> 8) & 0x3f;
+ s = (reg >> 0) & 0x7;
+ s -= 1;
+ return m * ((S5PCXX_CLOCK_REFERENCE) / (p << s));
+}
+
+static uint32_t s5p_get_a2mclk(void)
+{
+ return clkdiv(s3c_get_apllclk(), 4, 0x7);
+}
+
+static uint32_t s5p_get_moutpsysclk(void)
+{
+ if (readl(S5P_CLK_SRC0) & (1 << 24)) /* MUX_PSYS */
+ return s5p_get_a2mclk();
+ else
+ return s3c_get_mpllclk();
+}
+
+uint32_t s3c_get_hclk(void)
+{
+ return clkdiv(s5p_get_moutpsysclk(), 24, 0xf);
+}
+
+uint32_t s3c_get_pclk(void)
+{
+ return clkdiv(s3c_get_hclk(), 28, 0x7);
+}
+
+/* we are using the internal 'uclk1' as the UART source */
+static unsigned s3c_get_uart_clk_uclk1(void)
+{
+ unsigned clk = s3c_get_mpllclk(); /* TODO check for EPLL */
+ unsigned uartpdiv = ((readl(S5P_CLK_DIV4) >> 16) & 0x3) + 1; /* TODO this is UART0 only */
+ return clk / uartpdiv;
+}
+
+unsigned s3c_get_uart_clk(unsigned src) {
+ return (src & 1) ? s3c_get_uart_clk_uclk1() : s3c_get_pclk();
+}
+
+int s5pcxx_dump_clocks(void)
+{
+ printf("refclk: %7d kHz\n", S5PCXX_CLOCK_REFERENCE / 1000);
+ printf("apll: %7d kHz\n", s3c_get_apllclk() / 1000);
+ printf("mpll: %7d kHz\n", s3c_get_mpllclk() / 1000);
+/* printf("CPU: %7d kHz\n", s3c_get_cpuclk() / 1000); */
+ printf("hclk: %7d kHz\n", s3c_get_hclk() / 1000);
+ printf("pclk: %7d kHz\n", s3c_get_pclk() / 1000);
+ return 0;
+}
+
+late_initcall(s5pcxx_dump_clocks);
diff --git a/arch/arm/mach-samsung/gpio-s5pcxx.c b/arch/arm/mach-samsung/gpio-s5pcxx.c
new file mode 100644
index 0000000..604a63f
--- /dev/null
+++ b/arch/arm/mach-samsung/gpio-s5pcxx.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2012 Alexey Galakhov
+ * Copyright (C) 2012 Juergen Beisert, Pengutronix
+ *
+ * This codes bases partially on code from the Linux kernel:
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <io.h>
+#include <gpio.h>
+#include <mach/s3c-iomap.h>
+
+#define S3C_GPACON (S3C_GPIO_BASE)
+#define S3C_GPADAT (S3C_GPIO_BASE + 0x04)
+#define S3C_GPAPUD (S3C_GPIO_BASE + 0x08)
+
+static inline unsigned group_offset(unsigned group)
+{
+ return group * 0x20;
+}
+
+void gpio_set_value(unsigned gpio, int value)
+{
+ unsigned group = GET_GROUP(gpio);
+ unsigned bit = GET_BIT(gpio);
+ unsigned offset = group_offset(group);
+ uint32_t reg;
+
+ reg = readl(S3C_GPADAT + offset);
+ reg &= ~(1 << bit);
+ reg |= (!!value) << bit;
+ writel(reg, S3C_GPADAT + offset);
+}
+
+int gpio_get_value(unsigned gpio)
+{
+ unsigned group = GET_GROUP(gpio);
+ unsigned bit = GET_BIT(gpio);
+ unsigned offset = group_offset(group);
+ uint32_t reg;
+
+ /* value */
+ reg = readl(S3C_GPADAT + offset);
+
+ return !!(reg & (1 << bit));
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+ unsigned group = GET_GROUP(gpio);
+ unsigned bit = GET_BIT(gpio);
+ unsigned offset = group_offset(group);
+ uint32_t reg;
+
+ bit <<= 2;
+ reg = readl(S3C_GPACON + offset) & ~(0xf << bit);
+ writel(reg, S3C_GPACON + offset);
+
+ return 0;
+}
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+ unsigned group = GET_GROUP(gpio);
+ unsigned bit = GET_BIT(gpio);
+ unsigned offset = group_offset(group);
+ uint32_t reg;
+
+ gpio_set_value(gpio, value);
+
+ bit <<= 2;
+ reg = readl(S3C_GPACON + offset) & ~(0xf << bit);
+ reg |= 0x1 << bit;
+ writel(reg, S3C_GPACON + offset);
+
+ return 0;
+}
+
+
+/* 'gpio_mode' must be one of the 'GP?_*' macros */
+void s3c_gpio_mode(unsigned gpio_mode)
+{
+ unsigned group = GET_GROUP(gpio_mode);
+ unsigned bit = GET_BIT(gpio_mode);
+ unsigned func = GET_FUNC(gpio_mode);
+ unsigned offset = group_offset(group);
+ unsigned reg;
+
+ bit <<= 1;
+ if (PUD_PRESENT(gpio_mode)) {
+ reg = readl(S3C_GPAPUD + offset);
+ reg &= ~(PUD_MASK << bit);
+ reg |= GET_PUD(gpio_mode) << bit;
+ writel(reg, S3C_GPAPUD + offset);
+ }
+
+ bit <<= 1;
+ reg = readl(S3C_GPACON + offset) & ~(0xf << bit);
+ writel(reg | (func << bit), S3C_GPACON + offset);
+
+ if (func == 1) { /* output? if yes, also set the initial value */
+ reg = readl(S3C_GPADAT + offset) & ~(1 << (bit >> 2));
+ reg |= GET_GPIOVAL(gpio_mode) << (bit >> 2);
+ writel(reg, S3C_GPADAT + offset);
+ }
+
+}
diff --git a/arch/arm/mach-samsung/include/mach/clocks-s5pcxx.h b/arch/arm/mach-samsung/include/mach/clocks-s5pcxx.h
new file mode 100644
index 0000000..f9d49c5
--- /dev/null
+++ b/arch/arm/mach-samsung/include/mach/clocks-s5pcxx.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 Alexey Galakhov
+ *
+ * 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.
+ */
+
+# define S5P_APLL 0x00
+# define S5P_MPLL 0x08
+# define S5P_EPLL 0x10
+# define S5P_VPLL 0x20
+# define S5P_xPLL_LOCK (S5P_CLOCK_POWER_BASE)
+# define S5P_xPLL_CON (S5P_CLOCK_POWER_BASE + 0x100)
+# define S5P_xPLL_CON0 (S5P_xPLL_CON)
+# define S5P_xPLL_CON1 (S5P_xPLL_CON + 0x4)
+
+# define S5P_xPLLCON_GET_MDIV(x) (((x) >> 16) & 0x3ff)
+# define S5P_xPLLCON_GET_PDIV(x) (((x) >> 8) & 0x3f)
+# define S5P_xPLLCON_GET_SDIV(x) ((x) & 0x3)
+
+# define S5P_CLK_SRC0 (S5P_CLOCK_POWER_BASE + 0x200)
+# define S5P_CLK_SRC1 (S5P_CLOCK_POWER_BASE + 0x204)
+# define S5P_CLK_SRC2 (S5P_CLOCK_POWER_BASE + 0x208)
+# define S5P_CLK_SRC3 (S5P_CLOCK_POWER_BASE + 0x20C)
+# define S5P_CLK_SRC4 (S5P_CLOCK_POWER_BASE + 0x210)
+# define S5P_CLK_SRC5 (S5P_CLOCK_POWER_BASE + 0x214)
+# define S5P_CLK_SRC6 (S5P_CLOCK_BASE + 0x218)
+
+# define S5P_CLK_DIV0 (S5P_CLOCK_POWER_BASE + 0x300)
+# define S5P_CLK_DIV1 (S5P_CLOCK_POWER_BASE + 0x304)
+# define S5P_CLK_DIV2 (S5P_CLOCK_POWER_BASE + 0x308)
+# define S5P_CLK_DIV3 (S5P_CLOCK_POWER_BASE + 0x30C)
+# define S5P_CLK_DIV4 (S5P_CLOCK_POWER_BASE + 0x310)
+# define S5P_CLK_DIV5 (S5P_CLOCK_POWER_BASE + 0x314)
+# define S5P_CLK_DIV6 (S5P_CLOCK_POWER_BASE + 0x318)
+# define S5P_CLK_DIV7 (S5P_CLOCK_POWER_BASE + 0x31C)
+
+# define S5P_CLK_GATE_SCLK (S5P_CLOCK_POWER_BASE + 0x444)
+# define S5P_CLK_GATE_IP0 (S5P_CLOCK_POWER_BASE + 0x460)
+# define S5P_CLK_GATE_IP1 (S5P_CLOCK_POWER_BASE + 0x464)
+# define S5P_CLK_GATE_IP2 (S5P_CLOCK_POWER_BASE + 0x468)
+# define S5P_CLK_GATE_IP3 (S5P_CLOCK_POWER_BASE + 0x46C)
+# define S5P_CLK_GATE_IP4 (S5P_CLOCK_POWER_BASE + 0x470)
+# define S5P_CLK_GATE_BLOCK (S5P_CLOCK_POWER_BASE + 0x480)
+# define S5P_CLK_GATE_IP5 (S5P_CLOCK_POWER_BASE + 0x484)
+
+# define S5P_OTHERS (S5P_CLOCK_POWER_BASE + 0xE000)
+# define S5P_USB_PHY_CONTROL (S5P_CLOCK_POWER_BASE + 0xE80C)
diff --git a/arch/arm/mach-samsung/include/mach/gpio.h b/arch/arm/mach-samsung/include/mach/gpio.h
index 3723394..4d7d217 100644
--- a/arch/arm/mach-samsung/include/mach/gpio.h
+++ b/arch/arm/mach-samsung/include/mach/gpio.h
@@ -16,6 +16,9 @@
#ifdef CONFIG_ARCH_S3C24xx
# include <mach/iomux-s3c24x0.h>
#endif
+#ifdef CONFIG_ARCH_S5PCxx
+# include <mach/iomux-s5pcxx.h>
+#endif
void gpio_set_value(unsigned, int);
int gpio_direction_input(unsigned);
diff --git a/arch/arm/mach-samsung/include/mach/iomap-s5pcxx.h b/arch/arm/mach-samsung/include/mach/iomap-s5pcxx.h
new file mode 100644
index 0000000..cb05527
--- /dev/null
+++ b/arch/arm/mach-samsung/include/mach/iomap-s5pcxx.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2012 Alexey Galakhov
+ *
+ * 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
+ *
+ */
+
+/* S5PV210 device base addresses */
+
+#define S5P_CLOCK_POWER_BASE 0xE0100000
+#define S3C_GPIO_BASE 0xE0200000
+#define S3C_TIMER_BASE 0xE2500000
+#define S3C_WATCHDOG_BASE 0xE2700000
+#define S3C_UART_BASE 0xE2900000
+#define S3C_USB_HOST_BASE 0xEC200000
+#define S3C_NAND_BASE 0xB0E00000
+
+/* external IO space */
+#define S3C_CS0_BASE 0x80000000
+#define S3C_CS1_BASE 0x88000000
+#define S3C_CS2_BASE 0x90000000
+#define S3C_CS3_BASE 0x98000000
+#define S3C_CS4_BASE 0xA0000000
+#define S3C_CS5_BASE 0xA8000000
+
+#define S3C_SDRAM_BASE 0x20000000
+#define S3C_SDRAM_END (S3C_SDRAM_BASE + 0x60000000)
+
+#define S3C_UART1_BASE (S3C_UART_BASE)
+#define S3C_UART1_SIZE 0x400
+#define S3C_UART2_BASE (S3C_UART_BASE + 0x400)
+#define S3C_UART2_SIZE 0x400
+#define S3C_UART3_BASE (S3C_UART_BASE + 0x800)
+#define S3C_UART3_SIZE 0x400
+#define S3C_UART_HAS_UBRDIVSLOT
+#define S3C_UART_HAS_UINTM
diff --git a/arch/arm/mach-samsung/include/mach/iomux-s5pcxx.h b/arch/arm/mach-samsung/include/mach/iomux-s5pcxx.h
new file mode 100644
index 0000000..0677de4
--- /dev/null
+++ b/arch/arm/mach-samsung/include/mach/iomux-s5pcxx.h
@@ -0,0 +1,798 @@
+/*
+ * Copyright (C) 2012 Juergen Beisert
+ * Copyright (C) 2012 Alexey Galakhov
+ *
+ * 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.
+ */
+
+/* Tested with S5PV210 */
+
+#ifndef __MACH_IOMUX_S5PCXX_H
+# define __MACH_IOMUX_S5PCXX_H
+
+/* 3322222222221111111111
+ * 10987654321098765432109876543210
+ * ^^^^^^_ Bit offset
+ * ^^^^^_______ Group Number
+ * ^^^^____________ Function
+ * ^________________ initial GPIO out value
+ * ^_________________ Pull up/down feature present
+ * ^^__________________ initial pull up/down setting
+ */
+
+#define PIN(group,bit) ((group << 6) + bit)
+#define FUNC(x) (((x) & 0xf) << 11)
+#define GET_FUNC(x) (((x) >> 11) & 0xf)
+#define GET_GROUP(x) (((x) >> 6) & 0x1f)
+#define GET_BIT(x) ((x) & 0x3f)
+#define GET_GPIOVAL(x) (!!((x) & (1 << 15)))
+#define GPIO_OUT (1 << 11)
+#define GPIO_IN (0 << 11)
+#define GPIO_VAL(x) ((!!(x)) << 15)
+#define PUD_MASK 0x3
+#define PUD (1 << 16)
+#define PUD_PRESENT(x) (!!((x) & (1 << 16)))
+#define DISABLE_PUD (0 << 17)
+#define ENABLE_PU (2 << 17)
+#define ENABLE_PD (1 << 17)
+#define GET_PUD(x) (((x) >> 17) & PUD_MASK)
+
+/*
+ * To have a chance for simple GPIO manipulation routines
+ * define the GPIO numbers with a real simple scheme.
+ *
+ * Keep in mind: The 'GPIO_2_NO' creates a value to be used with the real gpio
+ * routines and *not* for the multiplexer routines!
+ */
+#define GPIO_2_NO(x,y) (PIN(x,y))
+
+/*
+ * Group A0: GPIO 0...7
+ * Used GPIO: 0...7
+ * These pins can also act as GPIO outputs
+ */
+#define GPA00 (PIN(0,0) | PUD)
+#define GPA00_GPIO (GPA00 | FUNC(0))
+#define GPA00_RXD0 (GPA00 | FUNC(2))
+#define GPA01 (PIN(0,1) | PUD)
+#define GPA01_GPIO (GPA01 | FUNC(0))
+#define GPA01_TXD0 (GPA01 | FUNC(2))
+#define GPA02 (PIN(0,2) | PUD)
+#define GPA02_GPIO (GPA02 | FUNC(0))
+#define GPA02_NCTS0 (GPA02 | FUNC(2))
+#define GPA03 (PIN(0,3) | PUD)
+#define GPA03_GPIO (GPA03 | FUNC(0))
+#define GPA03_NRTS0 (GPA03 | FUNC(2))
+#define GPA04 (PIN(0,4) | PUD)
+#define GPA04_GPIO (GPA04 | FUNC(0))
+#define GPA04_RXD1 (GPA04 | FUNC(2))
+#define GPA05 (PIN(0,5) | PUD)
+#define GPA05_GPIO (GPA05 | FUNC(0))
+#define GPA05_TXD1 (GPA05 | FUNC(2))
+#define GPA06 (PIN(0,6) | PUD)
+#define GPA06_GPIO (GPA06 | FUNC(0))
+#define GPA06_NCTS1 (GPA06 | FUNC(2))
+#define GPA07 (PIN(0,7) | PUD)
+#define GPA07_GPIO (GPA07 | FUNC(0))
+#define GPA07_NRTS1 (GPA07 | FUNC(2))
+
+/*
+ * Group A1: GPIO 0..3
+ * Used GPIO: 0..3
+ * These pins can also act as GPIO outputs
+ */
+#define GPA10 (PIN(1,0) | PUD)
+#define GPA10_GPIO (GPA10 | FUNC(0))
+#define GPA10_RXD2 (GPA10 | FUNC(2))
+#define GPA10_RXDAUD (GPA0 | FUNC(4))
+#define GPA11 (PIN(1,1) | PUD)
+#define GPA11_GPIO (GPA11 | FUNC(0))
+#define GPA11_TXD2 (GPA11 | FUNC(2))
+#define GPA11_TXDAUD (GPA1 | FUNC(4))
+#define GPA12 (PIN(1,2) | PUD)
+#define GPA12_GPIO (GPA12 | FUNC(0))
+#define GPA12_RXD3 (GPA12 | FUNC(2))
+#define GPA12_NCTS2 (GPA12 | FUNC(3))
+#define GPA13 (PIN(1,3) | PUD)
+#define GPA13_GPIO (GPA13 | FUNC(0))
+#define GPA13_TXD3 (GPA13 | FUNC(2))
+#define GPA13_NRTS2 (GPA13 | FUNC(3))
+
+
+/*
+ * Group B: GPIO 0...7
+ * Used GPIO: 0...7
+ * These pins can also act as GPIO outputs
+ */
+#define GPB0 (PIN(2,0) | PUD)
+#define GPB0_GPIO (GPB0 | FUNC(0))
+#define GPB0_SPI0_CLK (GPB0 | FUNC(2))
+#define GPB1 (PIN(2,1) | PUD)
+#define GPB1_GPIO (GPB1 | FUNC(0))
+#define GPB1_SPI0_NCS (GPB1 | FUNC(2))
+#define GPB2 (PIN(2,2) | PUD)
+#define GPB2_GPIO (GPB2 | FUNC(0))
+#define GPB2_SPI0_MISO (GPB2 | FUNC(2))
+#define GPB3 (PIN(2,3) | PUD)
+#define GPB3_GPIO (GPB3 | FUNC(0))
+#define GPB3_SPI0_MOSI (GPB3 | FUNC(2))
+#define GPB4 (PIN(2,4) | PUD)
+#define GPB4_GPIO (GPB4 | FUNC(0))
+#define GPB4_SPI1_CLK (GPB4 | FUNC(2))
+#define GPB5 (PIN(2,5) | PUD)
+#define GPB5_GPIO (GPB5 | FUNC(0))
+#define GPB5_SPI1_NCS (GPB5 | FUNC(0))
+#define GPB6 (PIN(2,6) | PUD)
+#define GPB6_GPIO (GPB6 | FUNC(0))
+#define GPB6_SPI1_MISO (GPB6 | FUNC(0))
+#define GPB7 (PIN(2,7) | PUD)
+#define GPB7_GPIO (GPB7 | FUNC(0))
+#define GPB7_SPI1_MOSI (GPB7 | FUNC(0))
+
+/*
+ * Group C0: GPIO 0...4
+ */
+#define GPC00 (PIN(3,0) | PUD)
+#define GPC00_GPIO (GPC00 | FUNC(0))
+#define GPC00_I2S1_SCLK (GPC00 | FUNC(2))
+#define GPC00_PCM1_SCLK (GPC00 | FUNC(3))
+#define GPC00_AC97_BITCLK (GPC00 | FUNC(4))
+#define GPC01 (PIN(3,1) | PUD)
+#define GPC01_GPIO (GPC01 | FUNC(0))
+#define GPC01_I2S1_CDCLK (GPC01 | FUNC(2))
+#define GPC01_PCM1_EXTCLK (GPC01 | FUNC(3))
+#define GPC01_AC97_NRESET (GPC01 | FUNC(4))
+#define GPC02 (PIN(3,2) | PUD)
+#define GPC02_GPIO (GPC02 | FUNC(0))
+#define GPC02_I2S1_LRCK (GPC02 | FUNC(2))
+#define GPC02_PCM1_FSYNC (GPC02 | FUNC(3))
+#define GPC02_AC97_SYNC (GPC02 | FUNC(4))
+#define GPC03 (PIN(3,3) | PUD)
+#define GPC03_GPIO (GPC03 | FUNC(0))
+#define GPC03_I2S1_SDI (GPC03 | FUNC(2))
+#define GPC03_PCM1_SIN (GPC03 | FUNC(3))
+#define GPC03_AC97_SDI (GPC03 | FUNC(4))
+#define GPC04 (PIN(3,4) | PUD)
+#define GPC04_GPIO (GPC04 | FUNC(0))
+#define GPC04_I2S1_SDO (GPC04 | FUNC(2))
+#define GPC04_PCM1_SOUT (GPC04 | FUNC(3))
+#define GPC04_AC97_SDO (GPC04 | FUNC(4))
+
+/*
+ * Group C1: GPIO 0...4
+ */
+#define GPC10 (PIN(4,0) | PUD)
+#define GPC10_GPIO (GPC10 | FUNC(0))
+#define GPC10_PCM2_SCLK (GPC10 | FUNC(2))
+#define GPC10_SPDIF_0_OUT (GPC10 | FUNC(3))
+#define GPC10_I2S2_SCLK (GPC10 | FUNC(4))
+#define GPC11 (PIN(4,1) | PUD)
+#define GPC11_GPIO (GPC11 | FUNC(0))
+#define GPC11_PCM2_EXTCLK (GPC11 | FUNC(2))
+#define GPC11_SPDIF_EXTCLK (GPC11 | FUNC(3))
+#define GPC11_I2S2_CDCLK (GPC11 | FUNC(4))
+#define GPC12 (PIN(4,2) | PUD)
+#define GPC12_GPIO (GPC12 | FUNC(0))
+#define GPC12_PCM2_FSYNC (GPC12 | FUNC(2))
+#define GPC12_LCD_FRM (GPC12 | FUNC(3))
+#define GPC12_I2S2_LRCK (GPC12 | FUNC(4))
+#define GPC13 (PIN(4,3) | PUD)
+#define GPC13_GPIO (GPC13 | FUNC(0))
+#define GPC13_PCM2_SIN (GPC13 | FUNC(2))
+#define GPC13_I2S2_SDI (GPC13 | FUNC(4))
+#define GPC14 (PIN(4,4) | PUD)
+#define GPC14_GPIO (GPC14 | FUNC(0))
+#define GPC14_PCM2_SOUT (GPC14 | FUNC(2))
+#define GPC14_I2S2_SDO (GPC14 | FUNC(4))
+
+/*
+ * Group D0: GPIO 0...3
+ */
+#define GPD00 (PIN(5,0) | PUD)
+#define GPD00_GPIO (GPD00 | FUNC(0))
+#define GPD00_TOUT_0 (GPD00 | FUNC(2))
+#define GPD01 (PIN(5,1) | PUD)
+#define GPD01_GPIO (GPD01 | FUNC(0))
+#define GPD01_TOUT_1 (GPD01 | FUNC(2))
+#define GPD02 (PIN(5,2) | PUD)
+#define GPD02_GPIO (GPD02 | FUNC(0))
+#define GPD02_TOUT_2 (GPD02 | FUNC(2))
+#define GPD03 (PIN(5,3) | PUD)
+#define GPD03_GPIO (GPD03 | FUNC(0))
+#define GPD03_TOUT_3 (GPD03 | FUNC(2))
+
+/*
+ * Group D1: GPIO 0...5
+ */
+#define GPD10 (PIN(6,0) | PUD)
+#define GPD10_GPIO (GPD10 | FUNC(0))
+#define GPD10_I2C0_SDA (GPD10 | FUNC(2))
+#define GPD11 (PIN(6,0) | PUD)
+#define GPD11_GPIO (GPD11 | FUNC(0))
+#define GPD11_I2C0_SCL (GPD11 | FUNC(2))
+#define GPD12 (PIN(6,0) | PUD)
+#define GPD12_GPIO (GPD12 | FUNC(0))
+#define GPD12_I2C1_SDA (GPD12 | FUNC(2))
+#define GPD13 (PIN(6,0) | PUD)
+#define GPD13_GPIO (GPD13 | FUNC(0))
+#define GPD13_I2C1_SCL (GPD13 | FUNC(2))
+#define GPD14 (PIN(6,0) | PUD)
+#define GPD14_GPIO (GPD14 | FUNC(0))
+#define GPD14_I2C2_SDA (GPD14 | FUNC(2))
+#define GPD15 (PIN(6,0) | PUD)
+#define GPD15_GPIO (GPD15 | FUNC(0))
+#define GPD15_I2C2_SCL (GPD15 | FUNC(2))
+
+/*
+ * Group E0: GPIO 0...7
+ */
+#define GPE00 (PIN(7,0) | PUD)
+#define GPE00_GPIO (GPE00 | FUNC(0))
+#define GPE00_CAM_A_PCLK (GPE00 | FUNC(2))
+#define GPE01 (PIN(7,1) | PUD)
+#define GPE01_GPIO (GPE01 | FUNC(0))
+#define GPE01_CAM_A_VSYNC (GPE01 | FUNC(2))
+#define GPE02 (PIN(7,2) | PUD)
+#define GPE02_GPIO (GPE02 | FUNC(0))
+#define GPE02_CAM_A_HREF (GPE02 | FUNC(2))
+#define GPE03 (PIN(7,3) | PUD)
+#define GPE03_GPIO (GPE03 | FUNC(0))
+#define GPE03_CAM_A_DATA0 (GPE03 | FUNC(2))
+#define GPE04 (PIN(7,4) | PUD)
+#define GPE04_GPIO (GPE04 | FUNC(0))
+#define GPE04_CAM_A_DATA1 (GPE04 | FUNC(2))
+#define GPE05 (PIN(7,5) | PUD)
+#define GPE05_GPIO (GPE05 | FUNC(0))
+#define GPE05_CAM_A_DATA2 (GPE05 | FUNC(2))
+#define GPE06 (PIN(7,6) | PUD)
+#define GPE06_GPIO (GPE06 | FUNC(0))
+#define GPE06_CAM_A_DATA3 (GPE06 | FUNC(2))
+#define GPE07 (PIN(7,7) | PUD)
+#define GPE07_GPIO (GPE07 | FUNC(0))
+#define GPE07_CAM_A_DATA4 (GPE07 | FUNC(2))
+
+/*
+ * Group E1: GPIO 0...4
+ */
+#define GPE10 (PIN(8,0) | PUD)
+#define GPE10_GPIO (GPE10 | FUNC(0))
+#define GPE10_CAM_A_DATA5 (GPE10 | FUNC(2))
+#define GPE11 (PIN(8,1) | PUD)
+#define GPE11_GPIO (GPE11 | FUNC(0))
+#define GPE11_CAM_A_DATA6 (GPE11 | FUNC(2))
+#define GPE12 (PIN(8,2) | PUD)
+#define GPE12_GPIO (GPE12 | FUNC(0))
+#define GPE12_CAM_A_DATA7 (GPE12 | FUNC(2))
+#define GPE13 (PIN(8,3) | PUD)
+#define GPE13_GPIO (GPE13 | FUNC(0))
+#define GPE13_CAM_A_CLKOUT (GPE13 | FUNC(2))
+#define GPE14 (PIN(8,4) | PUD)
+#define GPE14_GPIO (GPE14 | FUNC(0))
+#define GPE14_CAM_A_FIELD (GPE14 | FUNC(2))
+
+/*
+ * Group F0: GPIO 0...7
+ */
+#define GPF00 (PIN(9,0) | PUD)
+#define GPF00_GPIO (GPF00 | FUNC(0))
+#define GPF00_LCD_HSYNC (GPF00 | FUNC(2))
+#define GPF00_SYS_CS0 (GPF00 | FUNC(3))
+#define GPF00_VEN_HSYNC (GPF00 | FUNC(4))
+#define GPF01 (PIN(9,1) | PUD)
+#define GPF01_GPIO (GPF01 | FUNC(0))
+#define GPF01_LCD_VSYNC (GPF01 | FUNC(2))
+#define GPF01_SYS_CS1 (GPF01 | FUNC(3))
+#define GPF01_VEN_VSYNC (GPF01 | FUNC(4))
+#define GPF02 (PIN(9,2) | PUD)
+#define GPF02_GPIO (GPF02 | FUNC(0))
+#define GPF02_LCD_VDEN (GPF02 | FUNC(2))
+#define GPF02_SYS_RS (GPF02 | FUNC(3))
+#define GPF02_VEN_HREF (GPF02 | FUNC(4))
+#define GPF03 (PIN(9,3) | PUD)
+#define GPF03_GPIO (GPF03 | FUNC(0))
+#define GPF03_LCD_VCLK (GPF03 | FUNC(2))
+#define GPF03_SYS_WE (GPF03 | FUNC(3))
+#define GPF03_V601_CLK (GPF03 | FUNC(4))
+#define GPF04 (PIN(9,4) | PUD)
+#define GPF04_GPIO (GPF04 | FUNC(0))
+#define GPF04_LCD_VD0 (GPF04 | FUNC(2))
+#define GPF04_SYS_VS0 (GPF04 | FUNC(3))
+#define GPF04_VEN_DATA0 (GPF04 | FUNC(4))
+#define GPF05 (PIN(9,5) | PUD)
+#define GPF05_GPIO (GPF05 | FUNC(0))
+#define GPF05_LCD_VD1 (GPF05 | FUNC(2))
+#define GPF05_SYS_VD1 (GPF05 | FUNC(3))
+#define GPF05_VEN_DATA1 (GPF05 | FUNC(4))
+#define GPF06 (PIN(9,6) | PUD)
+#define GPF06_GPIO (GPF06 | FUNC(0))
+#define GPF06_LCD_VD2 (GPF06 | FUNC(2))
+#define GPF06_SYS_VD2 (GPF06 | FUNC(3))
+#define GPF06_VEN_DATA2 (GPF06 | FUNC(4))
+#define GPF07 (PIN(9,7) | PUD)
+#define GPF07_GPIO (GPF07 | FUNC(0))
+#define GPF07_LCD_VD3 (GPF07 | FUNC(2))
+#define GPF07_SYS_VD3 (GPF07 | FUNC(3))
+#define GPF07_VEN_DATA3 (GPF07 | FUNC(4))
+
+/*
+ * Group F1: GPIO 0...7
+ */
+#define GPF10 (PIN(10,0) | PUD)
+#define GPF10_GPIO (GPF10 | FUNC(0))
+#define GPF10_LCD_VD4 (GPF10 | FUNC(2))
+#define GPF10_SYS_VD4 (GPF10 | FUNC(3))
+#define GPF10_VEN_DATA4 (GPF10 | FUNC(4))
+#define GPF11 (PIN(10,1) | PUD)
+#define GPF11_GPIO (GPF11 | FUNC(0))
+#define GPF11_LCD_VD5 (GPF11 | FUNC(2))
+#define GPF11_SYS_VD5 (GPF11 | FUNC(3))
+#define GPF11_VEN_DATA5 (GPF11 | FUNC(4))
+#define GPF12 (PIN(10,2) | PUD)
+#define GPF12_GPIO (GPF12 | FUNC(0))
+#define GPF12_LCD_VD6 (GPF12 | FUNC(2))
+#define GPF12_SYS_VD6 (GPF12 | FUNC(3))
+#define GPF12_VEN_DATA6 (GPF12 | FUNC(4))
+#define GPF13 (PIN(10,3) | PUD)
+#define GPF13_GPIO (GPF13 | FUNC(0))
+#define GPF13_LCD_VD7 (GPF13 | FUNC(2))
+#define GPF13_SYS_VD7 (GPF13 | FUNC(3))
+#define GPF13_VEN_DATA7 (GPF13 | FUNC(4))
+#define GPF14 (PIN(10,4) | PUD)
+#define GPF14_GPIO (GPF14 | FUNC(0))
+#define GPF14_LCD_VD8 (GPF14 | FUNC(2))
+#define GPF14_SYS_VD8 (GPF14 | FUNC(3))
+#define GPF14_V656_DATA0 (GPF14 | FUNC(4))
+#define GPF15 (PIN(10,5) | PUD)
+#define GPF15_GPIO (GPF15 | FUNC(0))
+#define GPF15_LCD_VD9 (GPF15 | FUNC(2))
+#define GPF15_SYS_VD9 (GPF15 | FUNC(3))
+#define GPF15_V656_DATA1 (GPF15 | FUNC(4))
+#define GPF16 (PIN(10,6) | PUD)
+#define GPF16_GPIO (GPF16 | FUNC(0))
+#define GPF16_LCD_VD10 (GPF16 | FUNC(2))
+#define GPF16_SYS_VD10 (GPF16 | FUNC(3))
+#define GPF16_V656_DATA2 (GPF16 | FUNC(4))
+#define GPF17 (PIN(10,7) | PUD)
+#define GPF17_GPIO (GPF17 | FUNC(0))
+#define GPF17_LCD_VD11 (GPF17 | FUNC(2))
+#define GPF17_SYS_VD11 (GPF17 | FUNC(3))
+#define GPF17_V656_DATA3 (GPF17 | FUNC(4))
+
+/*
+ * Group F2: GPIO 0...7
+ */
+#define GPF20 (PIN(11,0) | PUD)
+#define GPF20_GPIO (GPF20 | FUNC(0))
+#define GPF20_LCD_VD_12 (GPF20 | FUNC(2))
+#define GPF20_SYS_VD_12 (GPF20 | FUNC(3))
+#define GPF20_V656_DATA_4 (GPF20 | FUNC(4))
+#define GPF21 (PIN(11,1) | PUD)
+#define GPF21_GPIO (GPF21 | FUNC(0))
+#define GPF21_LCD_VD_13 (GPF21 | FUNC(2))
+#define GPF21_SYS_VD_13 (GPF21 | FUNC(3))
+#define GPF21_V656_DATA_5 (GPF21 | FUNC(4))
+#define GPF22 (PIN(11,2) | PUD)
+#define GPF22_GPIO (GPF22 | FUNC(0))
+#define GPF22_LCD_VD_14 (GPF22 | FUNC(2))
+#define GPF22_SYS_VD_14 (GPF22 | FUNC(3))
+#define GPF22_V656_DATA_6 (GPF22 | FUNC(4))
+#define GPF23 (PIN(11,3) | PUD)
+#define GPF23_GPIO (GPF23 | FUNC(0))
+#define GPF23_LCD_VD_15 (GPF23 | FUNC(2))
+#define GPF23_SYS_VD_15 (GPF23 | FUNC(3))
+#define GPF23_V656_DATA_7 (GPF23 | FUNC(4))
+#define GPF24 (PIN(11,4) | PUD)
+#define GPF24_GPIO (GPF24 | FUNC(0))
+#define GPF24_LCD_VD_16 (GPF24 | FUNC(2))
+#define GPF24_SYS_VD_16 (GPF24 | FUNC(3))
+#define GPF25 (PIN(11,5) | PUD)
+#define GPF25_GPIO (GPF25 | FUNC(0))
+#define GPF25_LCD_VD_17 (GPF25 | FUNC(2))
+#define GPF25_SYS_VD_17 (GPF25 | FUNC(3))
+#define GPF26 (PIN(11,6) | PUD)
+#define GPF26_GPIO (GPF26 | FUNC(0))
+#define GPF26_LCD_VD_18 (GPF26 | FUNC(2))
+#define GPF26_SYS_VD_18 (GPF26 | FUNC(3))
+#define GPF27 (PIN(11,7) | PUD)
+#define GPF27_GPIO (GPF27 | FUNC(0))
+#define GPF27_LCD_VD_19 (GPF27 | FUNC(2))
+#define GPF27_SYS_VD_19 (GPF27 | FUNC(3))
+
+/*
+ * Group F3: GPIO 0...5
+ */
+#define GPF30 (PIN(12,0) | PUD)
+#define GPF30_GPIO (GPF30 | FUNC(0))
+#define GPF30_LCD_VD20 (GPF30 | FUNC(2))
+#define GPF30_SYS_VD20 (GPF30 | FUNC(3))
+#define GPF31 (PIN(12,1) | PUD)
+#define GPF31_GPIO (GPF31 | FUNC(0))
+#define GPF31_LCD_VD21 (GPF31 | FUNC(2))
+#define GPF31_SYS_VD21 (GPF31 | FUNC(3))
+#define GPF32 (PIN(12,2) | PUD)
+#define GPF32_GPIO (GPF32 | FUNC(0))
+#define GPF32_LCD_VD22 (GPF32 | FUNC(2))
+#define GPF32_SYS_VD22 (GPF32 | FUNC(3))
+#define GPF33 (PIN(12,3) | PUD)
+#define GPF33_GPIO (GPF33 | FUNC(0))
+#define GPF33_LCD_VD23 (GPF33 | FUNC(2))
+#define GPF33_SYS_VD23 (GPF33 | FUNC(3))
+#define GPF33_V656_CLK (GPF33 | FUNC(4))
+#define GPF34 (PIN(12,4) | PUD)
+#define GPF34_GPIO (GPF34 | FUNC(0))
+#define GPF34_VSYNC_LDI (GPF34 | FUNC(3))
+#define GPF35 (PIN(12,5) | PUD)
+#define GPF35_GPIO (GPF35 | FUNC(0))
+#define GPF35_SYS_OE (GPF35 | FUNC(3))
+#define GPF35_VEN_FIELD (GPF35 | FUNC(4))
+
+/*
+ * Group G0: GPIO 0...6
+ */
+#define GPG00 (PIN(13,0) | PUD)
+#define GPG00_GPIO (GPG00 | FUNC(0))
+#define GPG00_SD0_CLK (GPG00 | FUNC(2))
+#define GPG01 (PIN(13,1) | PUD)
+#define GPG01_GPIO (GPG01 | FUNC(0))
+#define GPG01_SD0_CMD (GPG01 | FUNC(2))
+#define GPG02 (PIN(13,2) | PUD)
+#define GPG02_GPIO (GPG02 | FUNC(0))
+#define GPG02_SD0_NCD (GPG02 | FUNC(2))
+#define GPG03 (PIN(13,3) | PUD)
+#define GPG03_GPIO (GPG03 | FUNC(0))
+#define GPG03_SD0_DATA0 (GPG03 | FUNC(2))
+#define GPG04 (PIN(13,4) | PUD)
+#define GPG04_GPIO (GPG04 | FUNC(0))
+#define GPG04_SD0_DATA1 (GPG04 | FUNC(2))
+#define GPG05 (PIN(13,5) | PUD)
+#define GPG05_GPIO (GPG05 | FUNC(0))
+#define GPG05_SD0_DATA2 (GPG05 | FUNC(2))
+#define GPG06 (PIN(13,6) | PUD)
+#define GPG06_GPIO (GPG06 | FUNC(0))
+#define GPG06_SD0_DATA3 (GPG06 | FUNC(2))
+
+/*
+ * Group G1: GPIO 0...6
+ */
+#define GPG10 (PIN(14,0) | PUD)
+#define GPG10_GPIO (GPG10 | FUNC(0))
+#define GPG10_SD1_CLK (GPG10 | FUNC(2))
+#define GPG11 (PIN(14,1) | PUD)
+#define GPG11_GPIO (GPG11 | FUNC(0))
+#define GPG11_SD1_CMD (GPG11 | FUNC(2))
+#define GPG12 (PIN(14,2) | PUD)
+#define GPG12_GPIO (GPG12 | FUNC(0))
+#define GPG12_SD1_NCD (GPG12 | FUNC(2))
+#define GPG13 (PIN(14,3) | PUD)
+#define GPG13_GPIO (GPG13 | FUNC(0))
+#define GPG13_SD1_DATA0 (GPG13 | FUNC(2))
+#define GPG13_SD0_DATA4 (GPG13 | FUNC(3))
+#define GPG14 (PIN(14,4) | PUD)
+#define GPG14_GPIO (GPG14 | FUNC(0))
+#define GPG14_SD1_DATA1 (GPG14 | FUNC(2))
+#define GPG14_SD0_DATA5 (GPG14 | FUNC(3))
+#define GPG15 (PIN(14,5) | PUD)
+#define GPG15_GPIO (GPG15 | FUNC(0))
+#define GPG15_SD1_DATA2 (GPG15 | FUNC(2))
+#define GPG15_SD0_DATA6 (GPG15 | FUNC(3))
+#define GPG16 (PIN(14,6) | PUD)
+#define GPG16_GPIO (GPG16 | FUNC(0))
+#define GPG16_SD1_DATA3 (GPG16 | FUNC(2))
+#define GPG16_SD0_DATA7 (GPG16 | FUNC(3))
+
+/*
+ * Group G2: GPIO 0...6
+ */
+#define GPG20 (PIN(15,0) | PUD)
+#define GPG20_GPIO (GPG20 | FUNC(0))
+#define GPG20_SD2_CLK (GPG20 | FUNC(2))
+#define GPG21 (PIN(15,1) | PUD)
+#define GPG21_GPIO (GPG21 | FUNC(0))
+#define GPG21_SD2_CMD (GPG21 | FUNC(2))
+#define GPG22 (PIN(15,2) | PUD)
+#define GPG22_GPIO (GPG22 | FUNC(0))
+#define GPG22_SD2_NCD (GPG22 | FUNC(2))
+#define GPG23 (PIN(15,3) | PUD)
+#define GPG23_GPIO (GPG23 | FUNC(0))
+#define GPG23_SD2_DATA0 (GPG23 | FUNC(2))
+#define GPG24 (PIN(15,4) | PUD)
+#define GPG24_GPIO (GPG24 | FUNC(0))
+#define GPG24_SD2_DATA1 (GPG24 | FUNC(2))
+#define GPG25 (PIN(15,5) | PUD)
+#define GPG25_GPIO (GPG25 | FUNC(0))
+#define GPG25_SD2_DATA2 (GPG25 | FUNC(2))
+#define GPG26 (PIN(15,6) | PUD)
+#define GPG26_GPIO (GPG26 | FUNC(0))
+#define GPG26_SD2_DATA3 (GPG26 | FUNC(2))
+
+/*
+ * Group G3: GPIO 0...6
+ */
+#define GPG30 (PIN(16,0) | PUD)
+#define GPG30_GPIO (GPG30 | FUNC(0))
+#define GPG30_SD3_CLK (GPG30 | FUNC(2))
+#define GPG31 (PIN(16,1) | PUD)
+#define GPG31_GPIO (GPG31 | FUNC(0))
+#define GPG31_SD3_CMD (GPG31 | FUNC(2))
+#define GPG32 (PIN(16,2) | PUD)
+#define GPG32_GPIO (GPG32 | FUNC(0))
+#define GPG32_SD3_NCD (GPG32 | FUNC(2))
+#define GPG33 (PIN(16,3) | PUD)
+#define GPG33_GPIO (GPG33 | FUNC(0))
+#define GPG33_SD3_DATA0 (GPG33 | FUNC(2))
+#define GPG33_SD2_DATA4 (GPG33 | FUNC(3))
+#define GPG34 (PIN(16,4) | PUD)
+#define GPG34_GPIO (GPG34 | FUNC(0))
+#define GPG34_SD3_DATA1 (GPG34 | FUNC(2))
+#define GPG34_SD2_DATA5 (GPG34 | FUNC(3))
+#define GPG35 (PIN(16,5) | PUD)
+#define GPG35_GPIO (GPG35 | FUNC(0))
+#define GPG35_SD3_DATA2 (GPG35 | FUNC(2))
+#define GPG35_SD2_DATA6 (GPG35 | FUNC(3))
+#define GPG36 (PIN(16,6) | PUD)
+#define GPG36_GPIO (GPG36 | FUNC(0))
+#define GPG36_SD3_DATA3 (GPG36 | FUNC(2))
+#define GPG36_SD2_DATA7 (GPG36 | FUNC(3))
+
+/*
+ * Group I - no GPIO
+ */
+#define GPI0 (PIN(17,0) | PUD)
+#define GPI0_I2S0_SCLK (GPI0 | FUNC(2))
+#define GPI0_PCM0_SCLK (GPI0 | FUNC(3))
+#define GPI1 (PIN(17,1) | PUD)
+#define GPI1_I2S0_CDCLK (GPI1 | FUNC(2))
+#define GPI1_PCM0_EXTCLK (GPI1 | FUNC(3))
+#define GPI2 (PIN(17,2) | PUD)
+#define GPI2_I2S0_LRCK (GPI2 | FUNC(2))
+#define GPI2_PCM0_FSYNC (GPI2 | FUNC(3))
+#define GPI3 (PIN(17,3) | PUD)
+#define GPI3_I2S0_SDI (GPI3 | FUNC(2))
+#define GPI3_PCM0_SIN (GPI3 | FUNC(3))
+#define GPI4 (PIN(17,4) | PUD)
+#define GPI4_I2S0_SDO0 (GPI4 | FUNC(2))
+#define GPI4_PCM0_SOUT (GPI4 | FUNC(3))
+#define GPI5 (PIN(17,5) | PUD)
+#define GPI5_I2S0_SDO1 (GPI5 | FUNC(2))
+#define GPI6 (PIN(17,6) | PUD)
+#define GPI6_I2S0_SDO2 (GPI6 | FUNC(2))
+
+/*
+ * Group J0: GPIO 0...7
+ */
+#define GPJ00 (PIN(18,0) | PUD)
+#define GPJ00_GPIO (GPJ00 | FUNC(0))
+#define GPJ00_MSM_ADDR0 (GPJ00 | FUNC(2))
+#define GPJ00_CAM_B_DATA0 (GPJ00 | FUNC(3))
+#define GPJ00_CF_ADDR0 (GPJ00 | FUNC(4))
+#define GPJ00_MIPI_BYTE_CLK (GPJ00 | FUNC(5))
+#define GPJ01 (PIN(18,1) | PUD)
+#define GPJ01_GPIO (GPJ01 | FUNC(0))
+#define GPJ01_MSM_ADDR1 (GPJ01 | FUNC(2))
+#define GPJ01_CAM_B_DATA1 (GPJ01 | FUNC(3))
+#define GPJ01_CF_ADDR1 (GPJ01 | FUNC(4))
+#define GPJ01_MIPI_ESC_CLK (GPJ01 | FUNC(5))
+#define GPJ02 (PIN(18,2) | PUD)
+#define GPJ02_GPIO (GPJ02 | FUNC(0))
+#define GPJ02_MSM_ADDR2 (GPJ02 | FUNC(2))
+#define GPJ02_CAM_B_DATA2 (GPJ02 | FUNC(3))
+#define GPJ02_CF_ADDR2 (GPJ02 | FUNC(4))
+#define GPJ02_TS_CLK (GPJ02 | FUNC(5))
+#define GPJ03 (PIN(18,3) | PUD)
+#define GPJ03_GPIO (GPJ03 | FUNC(0))
+#define GPJ03_MSM_ADDR3 (GPJ03 | FUNC(2))
+#define GPJ03_CAM_B_DATA3 (GPJ03 | FUNC(3))
+#define GPJ03_CF_IORDY (GPJ03 | FUNC(4))
+#define GPJ03_TS_SYNC (GPJ03 | FUNC(5))
+#define GPJ04 (PIN(18,4) | PUD)
+#define GPJ04_GPIO (GPJ04 | FUNC(0))
+#define GPJ04_MSM_ADDR4 (GPJ04 | FUNC(2))
+#define GPJ04_CAM_B_DATA4 (GPJ04 | FUNC(3))
+#define GPJ04_CF_INTRQ (GPJ04 | FUNC(4))
+#define GPJ04_TS_VAL (GPJ04 | FUNC(5))
+#define GPJ05 (PIN(18,5) | PUD)
+#define GPJ05_GPIO (GPJ05 | FUNC(0))
+#define GPJ05_MSM_ADDR5 (GPJ05 | FUNC(2))
+#define GPJ05_CAM_B_DATA5 (GPJ05 | FUNC(3))
+#define GPJ05_CF_DMARQ (GPJ05 | FUNC(4))
+#define GPJ05_TS_DATA (GPJ05 | FUNC(5))
+#define GPJ06 (PIN(18,6) | PUD)
+#define GPJ06_GPIO (GPJ06 | FUNC(0))
+#define GPJ06_MSM_ADDR6 (GPJ06 | FUNC(2))
+#define GPJ06_CAM_B_DATA6 (GPJ06 | FUNC(3))
+#define GPJ06_CF_NDRESET (GPJ06 | FUNC(4))
+#define GPJ06_TS_ERROR (GPJ06 | FUNC(5))
+#define GPJ07 (PIN(18,7) | PUD)
+#define GPJ07_GPIO (GPJ07 | FUNC(0))
+#define GPJ07_MSM_ADDR7 (GPJ07 | FUNC(2))
+#define GPJ07_CAM_B_DATA7 (GPJ07 | FUNC(3))
+#define GPJ07_CF_NDMACK (GPJ07 | FUNC(4))
+#define GPJ07_MHL_D0 (GPJ07 | FUNC(5))
+
+/*
+ * Group J1: GPIO 0...5
+ */
+#define GPJ10 (PIN(19,0) | PUD)
+#define GPJ10_GPIO (GPJ10 | FUNC(0))
+#define GPJ10_MSM_ADDR8 (GPJ10 | FUNC(2))
+#define GPJ10_CAM_B_PCLK (GPJ10 | FUNC(3))
+#define GPJ10_SROM_ADDR_16to220 (GPJ10 | FUNC(4))
+#define GPJ10_MHL_D1 (GPJ10 | FUNC(5))
+#define GPJ11 (PIN(19,1) | PUD)
+#define GPJ11_GPIO (GPJ11 | FUNC(0))
+#define GPJ11_MSM_ADDR9 (GPJ11 | FUNC(2))
+#define GPJ11_CAM_B_VSYNC (GPJ11 | FUNC(3))
+#define GPJ11_SROM_ADDR_16to221 (GPJ11 | FUNC(4))
+#define GPJ11_MHL_D2 (GPJ11 | FUNC(5))
+#define GPJ12 (PIN(19,2) | PUD)
+#define GPJ12_GPIO (GPJ12 | FUNC(0))
+#define GPJ12_MSM_ADDR10 (GPJ12 | FUNC(2))
+#define GPJ12_CAM_B_HREF (GPJ12 | FUNC(3))
+#define GPJ12_SROM_ADDR_16to222 (GPJ12 | FUNC(4))
+#define GPJ12_MHL_D3 (GPJ12 | FUNC(5))
+#define GPJ13 (PIN(19,3) | PUD)
+#define GPJ13_GPIO (GPJ13 | FUNC(0))
+#define GPJ13_MSM_ADDR11 (GPJ13 | FUNC(2))
+#define GPJ13_CAM_B_FIELD (GPJ13 | FUNC(3))
+#define GPJ13_SROM_ADDR_16to223 (GPJ13 | FUNC(4))
+#define GPJ13_MHL_D4 (GPJ13 | FUNC(5))
+#define GPJ14 (PIN(19,4) | PUD)
+#define GPJ14_GPIO (GPJ14 | FUNC(0))
+#define GPJ14_MSM_ADDR12 (GPJ14 | FUNC(2))
+#define GPJ14_CAM_B_CLKOUT (GPJ14 | FUNC(3))
+#define GPJ14_SROM_ADDR_16to224 (GPJ14 | FUNC(4))
+#define GPJ14_MHL_D5 (GPJ14 | FUNC(5))
+#define GPJ15 (PIN(19,5) | PUD)
+#define GPJ15_GPIO (GPJ15 | FUNC(0))
+#define GPJ15_MSM_ADDR13 (GPJ15 | FUNC(2))
+#define GPJ15_KP_COL0 (GPJ15 | FUNC(3))
+#define GPJ15_SROM_ADDR_16to225 (GPJ15 | FUNC(4))
+#define GPJ15_MHL_D6 (GPJ15 | FUNC(5))
+
+/*
+ * Group J2: GPIO 0...7
+ */
+#define GPJ20 (PIN(20,0) | PUD)
+#define GPJ20_GPIO (GPJ20 | FUNC(0))
+#define GPJ20_MSM_DATA0 (GPJ20 | FUNC(2))
+#define GPJ20_KP_COL1 (GPJ20 | FUNC(3))
+#define GPJ20_CF_DATA0 (GPJ20 | FUNC(4))
+#define GPJ20_MHL_D7 (GPJ20 | FUNC(5))
+#define GPJ21 (PIN(20,1) | PUD)
+#define GPJ21_GPIO (GPJ21 | FUNC(0))
+#define GPJ21_MSM_DATA1 (GPJ21 | FUNC(2))
+#define GPJ21_KP_COL2 (GPJ21 | FUNC(3))
+#define GPJ21_CF_DATA1 (GPJ21 | FUNC(4))
+#define GPJ21_MHL_D8 (GPJ21 | FUNC(5))
+#define GPJ22 (PIN(20,2) | PUD)
+#define GPJ22_GPIO (GPJ22 | FUNC(0))
+#define GPJ22_MSM_DATA2 (GPJ22 | FUNC(2))
+#define GPJ22_KP_COL3 (GPJ22 | FUNC(3))
+#define GPJ22_CF_DATA2 (GPJ22 | FUNC(4))
+#define GPJ22_MHL_D9 (GPJ22 | FUNC(5))
+#define GPJ23 (PIN(20,3) | PUD)
+#define GPJ23_GPIO (GPJ23 | FUNC(0))
+#define GPJ23_MSM_DATA3 (GPJ23 | FUNC(2))
+#define GPJ23_KP_COL4 (GPJ23 | FUNC(3))
+#define GPJ23_CF_DATA3 (GPJ23 | FUNC(4))
+#define GPJ23_MHL_D10 (GPJ23 | FUNC(5))
+#define GPJ24 (PIN(20,4) | PUD)
+#define GPJ24_GPIO (GPJ24 | FUNC(0))
+#define GPJ24_MSM_DATA4 (GPJ24 | FUNC(2))
+#define GPJ24_KP_COL5 (GPJ24 | FUNC(3))
+#define GPJ24_CF_DATA4 (GPJ24 | FUNC(4))
+#define GPJ24_MHL_D11 (GPJ24 | FUNC(5))
+#define GPJ25 (PIN(20,5) | PUD)
+#define GPJ25_GPIO (GPJ25 | FUNC(0))
+#define GPJ25_MSM_DATA5 (GPJ25 | FUNC(2))
+#define GPJ25_KP_COL6 (GPJ25 | FUNC(3))
+#define GPJ25_CF_DATA5 (GPJ25 | FUNC(4))
+#define GPJ25_MHL_D12 (GPJ25 | FUNC(5))
+#define GPJ26 (PIN(20,6) | PUD)
+#define GPJ26_GPIO (GPJ26 | FUNC(0))
+#define GPJ26_MSM_DATA6 (GPJ26 | FUNC(2))
+#define GPJ26_KP_COL7 (GPJ26 | FUNC(3))
+#define GPJ26_CF_DATA6 (GPJ26 | FUNC(4))
+#define GPJ26_MHL_D13 (GPJ26 | FUNC(5))
+#define GPJ27 (PIN(20,7) | PUD)
+#define GPJ27_GPIO (GPJ27 | FUNC(0))
+#define GPJ27_MSM_DATA7 (GPJ27 | FUNC(2))
+#define GPJ27_KP_ROW0 (GPJ27 | FUNC(3))
+#define GPJ27_CF_DATA7 (GPJ27 | FUNC(4))
+#define GPJ27_MHL_D14 (GPJ27 | FUNC(5))
+
+/*
+ * Group J3: GPIO 0...7
+ */
+#define GPJ30 (PIN(21,0) | PUD)
+#define GPJ30_GPIO (GPJ30 | FUNC(0))
+#define GPJ30_MSM_DATA8 (GPJ30 | FUNC(2))
+#define GPJ30_KP_ROW1 (GPJ30 | FUNC(3))
+#define GPJ30_CF_DATA8 (GPJ30 | FUNC(4))
+#define GPJ30_MHL_D15 (GPJ30 | FUNC(5))
+#define GPJ31 (PIN(21,1) | PUD)
+#define GPJ31_GPIO (GPJ31 | FUNC(0))
+#define GPJ31_MSM_DATA9 (GPJ31 | FUNC(2))
+#define GPJ31_KP_ROW2 (GPJ31 | FUNC(3))
+#define GPJ31_CF_DATA9 (GPJ31 | FUNC(4))
+#define GPJ31_MHL_D16 (GPJ31 | FUNC(5))
+#define GPJ32 (PIN(21,2) | PUD)
+#define GPJ32_GPIO (GPJ32 | FUNC(0))
+#define GPJ32_MSM_DATA10 (GPJ32 | FUNC(2))
+#define GPJ32_KP_ROW3 (GPJ32 | FUNC(3))
+#define GPJ32_CF_DATA10 (GPJ32 | FUNC(4))
+#define GPJ32_MHL_D17 (GPJ32 | FUNC(5))
+#define GPJ33 (PIN(21,3) | PUD)
+#define GPJ33_GPIO (GPJ33 | FUNC(0))
+#define GPJ33_MSM_DATA11 (GPJ33 | FUNC(2))
+#define GPJ33_KP_ROW4 (GPJ33 | FUNC(3))
+#define GPJ33_CF_DATA11 (GPJ33 | FUNC(4))
+#define GPJ33_MHL_D18 (GPJ33 | FUNC(5))
+#define GPJ34 (PIN(21,4) | PUD)
+#define GPJ34_GPIO (GPJ34 | FUNC(0))
+#define GPJ34_MSM_DATA12 (GPJ34 | FUNC(2))
+#define GPJ34_KP_ROW5 (GPJ34 | FUNC(3))
+#define GPJ34_CF_DATA12 (GPJ34 | FUNC(4))
+#define GPJ34_MHL_D19 (GPJ34 | FUNC(5))
+#define GPJ35 (PIN(21,5) | PUD)
+#define GPJ35_GPIO (GPJ35 | FUNC(0))
+#define GPJ35_MSM_DATA13 (GPJ35 | FUNC(2))
+#define GPJ35_KP_ROW6 (GPJ35 | FUNC(3))
+#define GPJ35_CF_DATA13 (GPJ35 | FUNC(4))
+#define GPJ35_MHL_D20 (GPJ35 | FUNC(5))
+#define GPJ36 (PIN(21,6) | PUD)
+#define GPJ36_GPIO (GPJ36 | FUNC(0))
+#define GPJ36_MSM_DATA14 (GPJ36 | FUNC(2))
+#define GPJ36_KP_ROW7 (GPJ36 | FUNC(3))
+#define GPJ36_CF_DATA14 (GPJ36 | FUNC(4))
+#define GPJ36_MHL_D21 (GPJ36 | FUNC(5))
+#define GPJ37 (PIN(21,7) | PUD)
+#define GPJ37_GPIO (GPJ37 | FUNC(0))
+#define GPJ37_MSM_DATA15 (GPJ37 | FUNC(2))
+#define GPJ37_KP_ROW8 (GPJ37 | FUNC(3))
+#define GPJ37_CF_DATA15 (GPJ37 | FUNC(4))
+#define GPJ37_MHL_D22 (GPJ37 | FUNC(5))
+
+/*
+ * Group J4: GPIO 0...4
+ */
+#define GPJ40 (PIN(22,0) | PUD)
+#define GPJ40_GPIO (GPJ40 | FUNC(0))
+#define GPJ40_MSM_NCS (GPJ40 | FUNC(2))
+#define GPJ40_KP_ROW9 (GPJ40 | FUNC(3))
+#define GPJ40_CF_NCS0 (GPJ40 | FUNC(4))
+#define GPJ40_MHL_D23 (GPJ40 | FUNC(5))
+#define GPJ41 (PIN(22,1) | PUD)
+#define GPJ41_GPIO (GPJ41 | FUNC(0))
+#define GPJ41_MSM_NWE (GPJ41 | FUNC(2))
+#define GPJ41_KP_ROW10 (GPJ41 | FUNC(3))
+#define GPJ41_CF_NCS1 (GPJ41 | FUNC(4))
+#define GPJ41_MHL_IDCK (GPJ41 | FUNC(5))
+#define GPJ42 (PIN(22,2) | PUD)
+#define GPJ42_GPIO (GPJ42 | FUNC(0))
+#define GPJ42_MSM_NR (GPJ42 | FUNC(2))
+#define GPJ42_KP_ROW11 (GPJ42 | FUNC(3))
+#define GPJ42_CF_IORN (GPJ42 | FUNC(4))
+#define GPJ42_MHL_IDCK (GPJ42 | FUNC(5))
+#define GPJ43 (PIN(22,3) | PUD)
+#define GPJ43_GPIO (GPJ43 | FUNC(0))
+#define GPJ43_MSM_NIRQ (GPJ43 | FUNC(2))
+#define GPJ43_KP_ROW12 (GPJ43 | FUNC(3))
+#define GPJ43_CF_IOWN (GPJ43 | FUNC(4))
+#define GPJ43_MHL_VSYNC (GPJ43 | FUNC(5))
+#define GPJ44 (PIN(22,4) | PUD)
+#define GPJ44_GPIO (GPJ44 | FUNC(0))
+#define GPJ44_MSM_ADVN (GPJ44 | FUNC(2))
+#define GPJ44_KP_ROW13 (GPJ44 | FUNC(3))
+#define GPJ44_SROM_ADDR_16to226 (GPJ44 | FUNC(4))
+#define GPJ44_MHL_DE (GPJ44 | FUNC(5))
+
+#endif /* __MACH_IOMUX_S5PCXX_H */
diff --git a/arch/arm/mach-samsung/include/mach/s3c-clocks.h b/arch/arm/mach-samsung/include/mach/s3c-clocks.h
index f4ca8fa..8f9d27b 100644
--- a/arch/arm/mach-samsung/include/mach/s3c-clocks.h
+++ b/arch/arm/mach-samsung/include/mach/s3c-clocks.h
@@ -25,5 +25,8 @@
#ifdef CONFIG_ARCH_S3C24xx
# include <mach/clocks-s3c24x0.h>
#endif
+#ifdef CONFIG_ARCH_S5PCxx
+# include <mach/clocks-s5pcxx.h>
+#endif
#endif /* __MACH_S3C_CLOCKS_H */
diff --git a/arch/arm/mach-samsung/include/mach/s3c-iomap.h b/arch/arm/mach-samsung/include/mach/s3c-iomap.h
index b1305da..a4d9505 100644
--- a/arch/arm/mach-samsung/include/mach/s3c-iomap.h
+++ b/arch/arm/mach-samsung/include/mach/s3c-iomap.h
@@ -22,3 +22,6 @@
#ifdef CONFIG_ARCH_S3C24xx
# include <mach/iomap-s3c24x0.h>
#endif
+#ifdef CONFIG_ARCH_S5PCxx
+# include <mach/iomap-s5pcxx.h>
+#endif
--
1.7.10
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 19+ messages in thread