2 * board-omap3evm-flash.c
4 * Copyright (c) 2008 Texas Instruments,
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/kernel.h>
12 #include <linux/platform_device.h>
13 #include <linux/mtd/mtd.h>
14 #include <linux/mtd/partitions.h>
15 #include <linux/mtd/nand.h>
16 #include <linux/mtd/onenand_regs.h>
17 #include <linux/types.h>
20 #include <asm/mach/flash.h>
21 #include <mach/onenand.h>
22 #include <mach/board.h>
23 #include <mach/gpmc.h>
24 #include <mach/nand.h>
26 #define ONENAND_MAP 0x20000000
28 static int omap3evm_onenand_setup(void __iomem *, int freq);
30 static struct mtd_partition omap3evm_onenand_partitions[] = {
32 .name = "xloader-onenand",
35 .mask_flags = MTD_WRITEABLE
38 .name = "uboot-onenand",
39 .offset = MTDPART_OFS_APPEND,
41 .mask_flags = MTD_WRITEABLE
44 .name = "params-onenand",
45 .offset = MTDPART_OFS_APPEND,
49 .name = "linux-onenand",
50 .offset = MTDPART_OFS_APPEND,
54 .name = "jffs2-onenand",
55 .offset = MTDPART_OFS_APPEND,
56 .size = MTDPART_SIZ_FULL,
60 static struct omap_onenand_platform_data omap3evm_onenand_data = {
61 .parts = omap3evm_onenand_partitions,
62 .nr_parts = ARRAY_SIZE(omap3evm_onenand_partitions),
63 .onenand_setup = omap3evm_onenand_setup,
64 .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */
67 static struct platform_device omap3evm_onenand_device = {
68 .name = "omap2-onenand",
71 .platform_data = &omap3evm_onenand_data,
75 static struct mtd_partition omap3evm_nand_partitions[] = {
76 /* All the partition sizes are listed in terms of NAND block size */
78 .name = "xloader-nand",
80 .size = 4*(128 * 1024),
81 .mask_flags = MTD_WRITEABLE
85 .offset = MTDPART_OFS_APPEND,
86 .size = 14*(128 * 1024),
87 .mask_flags = MTD_WRITEABLE
90 .name = "params-nand",
92 .offset = MTDPART_OFS_APPEND,
93 .size = 2*(128 * 1024)
97 .offset = MTDPART_OFS_APPEND,
98 .size = 40*(128 * 1024)
101 .name = "jffs2-nand",
102 .size = MTDPART_SIZ_FULL,
103 .offset = MTDPART_OFS_APPEND,
107 static struct omap_nand_platform_data omap3evm_nand_data = {
108 .parts = omap3evm_nand_partitions,
109 .nr_parts = ARRAY_SIZE(omap3evm_nand_partitions),
111 .dma_channel = -1, /* disable DMA in OMAP NAND driver */
115 static struct resource omap3evm_nand_resource = {
116 .flags = IORESOURCE_MEM,
119 static struct platform_device omap3evm_nand_device = {
120 .name = "omap2-nand",
123 .platform_data = &omap3evm_nand_data,
126 .resource = &omap3evm_nand_resource,
130 * omap3evm_onenand_setup - Set the onenand sync mode
131 * @onenand_base: The onenand base address in GPMC memory map
135 static int omap3evm_onenand_setup(void __iomem *onenand_base, int freq)
137 /* nothing is required to be setup for onenand as of now */
141 void __init omap3evm_flash_init(void)
144 u8 onenandcs = GPMC_CS_NUM + 1, nandcs = GPMC_CS_NUM + 1;
145 u32 gpmc_base_add = OMAP34XX_GPMC_VIRT;
147 while (cs < GPMC_CS_NUM) {
149 ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
152 * xloader/Uboot would have programmed the NAND/oneNAND
153 * base address for us This is a ugly hack. The proper
154 * way of doing this is to pass the setup of u-boot up
155 * to kernel using kernel params - something on the
156 * lines of machineID. Check if NAND/oneNAND is configured
158 if ((ret & 0xC00) == 0x800) {
160 if (nandcs > GPMC_CS_NUM)
163 ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
164 if ((ret & 0x3F) == (ONENAND_MAP >> 24))
169 if ((nandcs > GPMC_CS_NUM) && (onenandcs > GPMC_CS_NUM)) {
170 printk(KERN_INFO "NAND/OneNAND: Unable to find configuration "
175 if (nandcs < GPMC_CS_NUM) {
176 omap3evm_nand_data.cs = nandcs;
177 omap3evm_nand_data.gpmc_cs_baseaddr = (void *)(gpmc_base_add +
178 GPMC_CS0_BASE + nandcs*GPMC_CS_SIZE);
179 omap3evm_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add);
181 if (platform_device_register(&omap3evm_nand_device) < 0) {
182 printk(KERN_ERR "Unable to register NAND device\n");
186 if (onenandcs < GPMC_CS_NUM) {
187 omap3evm_onenand_data.cs = onenandcs;
188 if (platform_device_register(&omap3evm_onenand_device) < 0)
189 printk(KERN_ERR "Unable to register OneNAND device\n");