]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
ARM: SAMSUNG: Add platform support code for OneNAND controller
authorMarek Szyprowski <m.szyprowski@samsung.com>
Thu, 20 May 2010 06:59:05 +0000 (08:59 +0200)
committerBen Dooks <ben-linux@fluff.org>
Thu, 20 May 2010 08:48:36 +0000 (17:48 +0900)
This patch adds setup code for Samsung OneNAND controller driver. The
driver needs to be aware on which SoC it is running, so the actual
device id is being changed in cpu init code. S3C64xx SoCs have 2 OneNAND
controllers while S5PC100 and S5PC110 has only one.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
[ben-linux@fluff.org: sort map.h entries]
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
19 files changed:
arch/arm/mach-s3c64xx/Kconfig
arch/arm/mach-s3c64xx/Makefile
arch/arm/mach-s3c64xx/dev-onenand1.c [new file with mode: 0644]
arch/arm/mach-s3c64xx/include/mach/irqs.h
arch/arm/mach-s3c64xx/include/mach/map.h
arch/arm/mach-s3c64xx/s3c6400.c
arch/arm/mach-s3c64xx/s3c6410.c
arch/arm/mach-s5pc100/cpu.c
arch/arm/mach-s5pc100/include/mach/map.h
arch/arm/mach-s5pv210/Kconfig
arch/arm/mach-s5pv210/Makefile
arch/arm/mach-s5pv210/dev-onenand.c [new file with mode: 0644]
arch/arm/mach-s5pv210/include/mach/map.h
arch/arm/plat-samsung/Kconfig
arch/arm/plat-samsung/Makefile
arch/arm/plat-samsung/dev-onenand.c [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/devs.h
arch/arm/plat-samsung/include/plat/onenand-core.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/regs-onenand.h [new file with mode: 0644]

index 69e9fbfea9175a7e09b5e86c500a9e47ebd82d8c..805da81095f0ebf199a9a3c6d562564a2d33967e 100644 (file)
@@ -35,6 +35,11 @@ config S3C64XX_SETUP_SDHCI
          Internal configuration for default SDHCI setup for S3C6400 and
          S3C6410 SoCs.
 
+config S3C64XX_DEV_ONENAND1
+       bool
+       help
+         Compile in platform device definition for OneNAND1 controller
+
 # platform specific device setup
 
 config S3C64XX_SETUP_I2C0
index a10f1fc6b023441b5b7dd3960d7c45906117b773..17883187c4cb32bc6be9a0ededa8cd08d74ec2bb 100644 (file)
@@ -59,3 +59,4 @@ obj-y                         += dev-uart.o
 obj-y                          += dev-audio.o
 obj-$(CONFIG_S3C64XX_DEV_SPI)  += dev-spi.o
 obj-$(CONFIG_S3C64XX_DEV_TS)   += dev-ts.o
+obj-$(CONFIG_S3C64XX_DEV_ONENAND1)     += dev-onenand1.o
diff --git a/arch/arm/mach-s3c64xx/dev-onenand1.c b/arch/arm/mach-s3c64xx/dev-onenand1.c
new file mode 100644 (file)
index 0000000..92ffd5b
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * linux/arch/arm/mach-s3c64xx/dev-onenand1.c
+ *
+ *  Copyright (c) 2008-2010 Samsung Electronics
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * S3C64XX series device definition for OneNAND devices
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+static struct resource s3c64xx_onenand1_resources[] = {
+       [0] = {
+               .start  = S3C64XX_PA_ONENAND1,
+               .end    = S3C64XX_PA_ONENAND1 + 0x400 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = S3C64XX_PA_ONENAND1_BUF,
+               .end    = S3C64XX_PA_ONENAND1_BUF + S3C64XX_SZ_ONENAND1_BUF - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [2] = {
+               .start  = IRQ_ONENAND1,
+               .end    = IRQ_ONENAND1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device s3c64xx_device_onenand1 = {
+       .name           = "samsung-onenand",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(s3c64xx_onenand1_resources),
+       .resource       = s3c64xx_onenand1_resources,
+};
+
+void s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
+{
+       struct onenand_platform_data *pd;
+
+       pd = kmemdup(pdata, sizeof(struct onenand_platform_data), GFP_KERNEL);
+       if (!pd)
+               printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+       s3c64xx_device_onenand1.dev.platform_data = pd;
+}
index e9ab4ac0b9a822e9288fa193678c7219c711889e..8e2df26cf14a5dac4e643e9167163c671fcdae02 100644 (file)
 
 #define NR_IRQS        (IRQ_BOARD_END + 1)
 
+/* Compatibility */
+
+#define IRQ_ONENAND    IRQ_ONENAND0
+
 #endif /* __ASM_MACH_S3C64XX_IRQS_H */
 
index 9fdd50c8c767473fed80df430b89de0a38bf7ec3..b6fb8920b41353bee38fba9c9bfe4df23f10bccf 100644 (file)
 
 #define S3C64XX_PA_SROM                (0x70000000)
 
+#define S3C64XX_PA_ONENAND0    (0x70100000)
+#define S3C64XX_PA_ONENAND0_BUF        (0x20000000)
+#define S3C64XX_SZ_ONENAND0_BUF (SZ_64M)
+
+/* NAND and OneNAND1 controllers occupy the same register region
+   (depending on SoC POP version) */
+#define S3C64XX_PA_ONENAND1    (0x70200000)
+#define S3C64XX_PA_ONENAND1_BUF        (0x28000000)
+#define S3C64XX_SZ_ONENAND1_BUF        (SZ_64M)
+
 #define S3C64XX_PA_NAND                (0x70200000)
 #define S3C64XX_PA_FB          (0x77100000)
 #define S3C64XX_PA_USB_HSOTG   (0x7C000000)
 #define S3C_PA_IIC             S3C64XX_PA_IIC0
 #define S3C_PA_IIC1            S3C64XX_PA_IIC1
 #define S3C_PA_NAND            S3C64XX_PA_NAND
+#define S3C_PA_ONENAND         S3C64XX_PA_ONENAND0
+#define S3C_PA_ONENAND_BUF     S3C64XX_PA_ONENAND0_BUF
+#define S3C_SZ_ONENAND_BUF     S3C64XX_SZ_ONENAND0_BUF
 #define S3C_PA_FB              S3C64XX_PA_FB
 #define S3C_PA_USBHOST         S3C64XX_PA_USBHOST
 #define S3C_PA_USB_HSOTG       S3C64XX_PA_USB_HSOTG
index 707e34e3afd1a7fc9cc5abd37fd4bba74330cbd2..5e93fe3f3f409a16f4232d8e0fb5326de99652c3 100644 (file)
@@ -37,6 +37,7 @@
 #include <plat/clock.h>
 #include <plat/sdhci.h>
 #include <plat/iic-core.h>
+#include <plat/onenand-core.h>
 #include <mach/s3c6400.h>
 
 void __init s3c6400_map_io(void)
@@ -51,6 +52,9 @@ void __init s3c6400_map_io(void)
        s3c_i2c0_setname("s3c2440-i2c");
 
        s3c_device_nand.name = "s3c6400-nand";
+
+       s3c_onenand_setname("s3c6400-onenand");
+       s3c64xx_onenand1_setname("s3c6400-onenand");
 }
 
 void __init s3c6400_init_clocks(int xtal)
index 3ab695c691eefe05018d91f934779e1fc01cd3f6..014401c39f36239f51105a13033fbf3f3c46a1e9 100644 (file)
@@ -39,6 +39,7 @@
 #include <plat/sdhci.h>
 #include <plat/iic-core.h>
 #include <plat/adc.h>
+#include <plat/onenand-core.h>
 #include <mach/s3c6400.h>
 #include <mach/s3c6410.h>
 
@@ -55,6 +56,8 @@ void __init s3c6410_map_io(void)
 
        s3c_device_adc.name     = "s3c64xx-adc";
        s3c_device_nand.name = "s3c6400-nand";
+       s3c_onenand_setname("s3c6410-onenand");
+       s3c64xx_onenand1_setname("s3c6410-onenand");
 }
 
 void __init s3c6410_init_clocks(int xtal)
index d79e7574a8524c8bb4fa22124c552f0b6fcb0729..cb37ffee05b27b51fdb39755da984d6b36185b65 100644 (file)
@@ -41,6 +41,8 @@
 #include <plat/clock.h>
 #include <plat/sdhci.h>
 #include <plat/iic-core.h>
+#include <plat/onenand-core.h>
+
 #include <plat/s5pc100.h>
 
 /* Initial IO mappings */
@@ -82,6 +84,8 @@ void __init s5pc100_map_io(void)
        /* the i2c devices are directly compatible with s3c2440 */
        s3c_i2c0_setname("s3c2440-i2c");
        s3c_i2c1_setname("s3c2440-i2c");
+
+       s3c_onenand_setname("s5pc100-onenand");
 }
 
 void __init s5pc100_init_clocks(int xtal)
index 4681ebe8bef66defff9757e0b2a854dc29db7c39..aba3bb4e3412c7f2fac817d02803c7c6e4e912c6 100644 (file)
@@ -31,6 +31,9 @@
  *
  */
 
+#define S5PC100_PA_ONENAND_BUF (0xB0000000)
+#define S5PC100_SZ_ONENAND_BUF (SZ_256M - SZ_32M)
+
 /* Chip ID */
 #define S5PC100_PA_CHIPID      (0xE0000000)
 #define S5PC1XX_PA_CHIPID      S5PC100_PA_CHIPID
@@ -60,6 +63,8 @@
 #define S5PC1XX_PA_VIC(x)      (S5PC100_PA_VIC + ((x) * S5PC100_PA_VIC_OFFSET))
 #define S5PC1XX_VA_VIC(x)      (S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET))
 
+#define S5PC100_PA_ONENAND     (0xE7100000)
+
 /* DMA */
 #define S5PC100_PA_MDMA                (0xE8100000)
 #define S5PC100_PA_PDMA0       (0xE9000000)
 #define S3C_PA_HSMMC2          S5PC100_PA_HSMMC2
 #define S3C_PA_KEYPAD          S5PC100_PA_KEYPAD
 #define S3C_PA_TSADC           S5PC100_PA_TSADC
+#define S3C_PA_ONENAND         S5PC100_PA_ONENAND
+#define S3C_PA_ONENAND_BUF     S5PC100_PA_ONENAND_BUF
+#define S3C_SZ_ONENAND_BUF     S5PC100_SZ_ONENAND_BUF
 
 #endif /* __ASM_ARCH_C100_MAP_H */
index 7601c28e240b9e32aa2a5c2550a93a37a539f6d1..ef063e2890c580a05ac37fdec3bd034c577296a2 100644 (file)
@@ -21,6 +21,11 @@ choice
        depends on ARCH_S5PV210
        default MACH_SMDKV210
 
+config S5PC110_DEV_ONENAND
+       bool
+       help
+         Compile in platform device definition for OneNAND1 controller
+
 config MACH_SMDKV210
        bool "SMDKV210"
        select CPU_S5PV210
index 99827813d293afc96b545aac1b6cffcf5f43524b..610b9496c186891831399e49dc8aaf2b852b7bbc 100644 (file)
@@ -23,3 +23,4 @@ obj-$(CONFIG_MACH_SMDKC110)   += mach-smdkc110.o
 # device support
 
 obj-y                          += dev-audio.o
+obj-$(CONFIG_S5PC110_DEV_ONENAND) += dev-onenand.o
\ No newline at end of file
diff --git a/arch/arm/mach-s5pv210/dev-onenand.c b/arch/arm/mach-s5pv210/dev-onenand.c
new file mode 100644 (file)
index 0000000..34997b7
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * linux/arch/arm/mach-s5pv210/dev-onenand.c
+ *
+ *  Copyright (c) 2008-2010 Samsung Electronics
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * S5PC110 series device definition for OneNAND devices
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+static struct resource s5pc110_onenand_resources[] = {
+       [0] = {
+               .start  = S5PC110_PA_ONENAND,
+               .end    = S5PC110_PA_ONENAND + SZ_128K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = S5PC110_PA_ONENAND_DMA,
+               .end    = S5PC110_PA_ONENAND_DMA + SZ_2K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+struct platform_device s5pc110_device_onenand = {
+       .name           = "s5pc110-onenand",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s5pc110_onenand_resources),
+       .resource       = s5pc110_onenand_resources,
+};
+
+void s5pc110_onenand_set_platdata(struct onenand_platform_data *pdata)
+{
+       struct onenand_platform_data *pd;
+
+       pd = kmemdup(pdata, sizeof(struct onenand_platform_data), GFP_KERNEL);
+       if (!pd)
+               printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+       s5pc110_device_onenand.dev.platform_data = pd;
+}
index 5adcb9f26e449ef76504b10244cbd3570fb710dc..d2a505fa1fff40851b506fab37e63ef697b6aec2 100644 (file)
@@ -16,6 +16,9 @@
 #include <plat/map-base.h>
 #include <plat/map-s5p.h>
 
+#define S5PC110_PA_ONENAND     (0xB0000000)
+#define S5PC110_PA_ONENAND_DMA (0xB0600000)
+
 #define S5PV210_PA_CHIPID      (0xE0000000)
 #define S5P_PA_CHIPID          S5PV210_PA_CHIPID
 
index 229919e9744c8ee3f2cf0b570c48247946f0d6bb..58cc26d53092e90a1225578b5ac5864a6c5ed2ce 100644 (file)
@@ -190,6 +190,11 @@ config S3C_DEV_NAND
        help
          Compile in platform device definition for NAND controller
 
+config S3C_DEV_ONENAND
+       bool
+       help
+         Compile in platform device definition for OneNAND controller
+
 config S3C_DEV_RTC
        bool
        help
index 48288499a3b9f8a3a2fceb5be1d5047f88fcd7c1..595d86b8b893cd7b9e41efc5810e4b32416a4242 100644 (file)
@@ -41,6 +41,7 @@ obj-y                         += dev-uart.o
 obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
 obj-$(CONFIG_S3C_DEV_USB_HSOTG)        += dev-usb-hsotg.o
 obj-$(CONFIG_S3C_DEV_NAND)     += dev-nand.o
+obj-$(CONFIG_S3C_DEV_ONENAND)  += dev-onenand.o
 obj-$(CONFIG_S3C_DEV_RTC)      += dev-rtc.o
 
 obj-$(CONFIG_SAMSUNG_DEV_ADC)  += dev-adc.o
diff --git a/arch/arm/plat-samsung/dev-onenand.c b/arch/arm/plat-samsung/dev-onenand.c
new file mode 100644 (file)
index 0000000..45ec732
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * linux/arch/arm/plat-samsung/dev-onenand.c
+ *
+ *  Copyright (c) 2008-2010 Samsung Electronics
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * S3C64XX/S5PC100 series device definition for OneNAND devices
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+static struct resource s3c_onenand_resources[] = {
+       [0] = {
+               .start  = S3C_PA_ONENAND,
+               .end    = S3C_PA_ONENAND + 0x400 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = S3C_PA_ONENAND_BUF,
+               .end    = S3C_PA_ONENAND_BUF + S3C_SZ_ONENAND_BUF - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [2] = {
+               .start  = IRQ_ONENAND,
+               .end    = IRQ_ONENAND,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device s3c_device_onenand = {
+       .name           = "samsung-onenand",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s3c_onenand_resources),
+       .resource       = s3c_onenand_resources,
+};
+
+void s3c_onenand_set_platdata(struct onenand_platform_data *pdata)
+{
+       struct onenand_platform_data *pd;
+
+       pd = kmemdup(pdata, sizeof(struct onenand_platform_data), GFP_KERNEL);
+       if (!pd)
+               printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+       s3c_device_onenand.dev.platform_data = pd;
+}
index ef69e56b28854e508d007cb14b92dc5bbf05022b..57ec56ade02519db454af97b4c9de06837ba830b 100644 (file)
@@ -60,6 +60,9 @@ extern struct platform_device s3c_device_spi1;
 extern struct platform_device s3c_device_hwmon;
 
 extern struct platform_device s3c_device_nand;
+extern struct platform_device s3c_device_onenand;
+extern struct platform_device s3c64xx_device_onenand1;
+extern struct platform_device s5pc110_device_onenand;
 
 extern struct platform_device s3c_device_usbgadget;
 extern struct platform_device s3c_device_usb_hsotg;
diff --git a/arch/arm/plat-samsung/include/plat/onenand-core.h b/arch/arm/plat-samsung/include/plat/onenand-core.h
new file mode 100644 (file)
index 0000000..7701cb7
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * linux/arch/arm/plat-samsung/onenand-core.h
+ *
+ *  Copyright (c) 2010 Samsung Electronics
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *  Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * Samsung OneNAD Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_ONENAND_CORE_H
+#define __ASM_ARCH_ONENAND_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c_onenand_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_ONENAND
+       s3c_device_onenand.name = name;
+#endif
+}
+
+static inline void s3c64xx_onenand1_setname(char *name)
+{
+#ifdef CONFIG_S3C64XX_DEV_ONENAND1
+       s3c64xx_device_onenand1.name = name;
+#endif
+}
+
+#endif /* __ASM_ARCH_ONENAND_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-onenand.h b/arch/arm/plat-samsung/include/plat/regs-onenand.h
new file mode 100644 (file)
index 0000000..930ea8b
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * linux/arch/arm/plat-s3c/include/plat/regs-onenand.h
+ *
+ *  Copyright (C) 2008-2010 Samsung Electronics
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __SAMSUNG_ONENAND_H__
+#define __SAMSUNG_ONENAND_H__
+
+#include <mach/hardware.h>
+
+/*
+ * OneNAND Controller
+ */
+#define MEM_CFG_OFFSET         0x0000
+#define BURST_LEN_OFFSET       0x0010
+#define MEM_RESET_OFFSET       0x0020
+#define INT_ERR_STAT_OFFSET    0x0030
+#define INT_ERR_MASK_OFFSET    0x0040
+#define INT_ERR_ACK_OFFSET     0x0050
+#define ECC_ERR_STAT_OFFSET    0x0060
+#define MANUFACT_ID_OFFSET     0x0070
+#define DEVICE_ID_OFFSET       0x0080
+#define DATA_BUF_SIZE_OFFSET   0x0090
+#define BOOT_BUF_SIZE_OFFSET   0x00A0
+#define BUF_AMOUNT_OFFSET      0x00B0
+#define TECH_OFFSET            0x00C0
+#define FBA_WIDTH_OFFSET       0x00D0
+#define FPA_WIDTH_OFFSET       0x00E0
+#define FSA_WIDTH_OFFSET       0x00F0
+#define TRANS_SPARE_OFFSET     0x0140
+#define DBS_DFS_WIDTH_OFFSET   0x0160
+#define INT_PIN_ENABLE_OFFSET  0x01A0
+#define ACC_CLOCK_OFFSET       0x01C0
+#define FLASH_VER_ID_OFFSET    0x01F0
+#define FLASH_AUX_CNTRL_OFFSET 0x0300          /* s3c64xx only */
+
+#define ONENAND_MEM_RESET_HOT  0x3
+#define ONENAND_MEM_RESET_COLD 0x2
+#define ONENAND_MEM_RESET_WARM 0x1
+
+#define CACHE_OP_ERR           (1 << 13)
+#define RST_CMP                        (1 << 12)
+#define RDY_ACT                        (1 << 11)
+#define INT_ACT                        (1 << 10)
+#define UNSUP_CMD              (1 << 9)
+#define LOCKED_BLK             (1 << 8)
+#define BLK_RW_CMP             (1 << 7)
+#define ERS_CMP                        (1 << 6)
+#define PGM_CMP                        (1 << 5)
+#define LOAD_CMP               (1 << 4)
+#define ERS_FAIL               (1 << 3)
+#define PGM_FAIL               (1 << 2)
+#define INT_TO                 (1 << 1)
+#define LD_FAIL_ECC_ERR                (1 << 0)
+
+#define TSRF                   (1 << 0)
+
+#endif