]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/board-omap3evm-flash.c
b58b7c6b1af7e01e79b162fa58476fa20c835053
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / board-omap3evm-flash.c
1 /*
2  * board-omap3evm-flash.c
3  *
4  * Copyright (c) 2008 Texas Instruments,
5  *
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.
9  */
10
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>
18 #include <linux/io.h>
19
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>
25
26 #define ONENAND_MAP             0x20000000
27
28 static int omap3evm_onenand_setup(void __iomem *, int freq);
29
30 static struct mtd_partition omap3evm_onenand_partitions[] = {
31         {
32                 .name           = "xloader-onenand",
33                 .offset         = 0,
34                 .size           = 4*(64*2048),
35                 .mask_flags     = MTD_WRITEABLE
36         },
37         {
38                 .name           = "uboot-onenand",
39                 .offset         = MTDPART_OFS_APPEND,
40                 .size           =  15*(64*2048),
41                 .mask_flags     = MTD_WRITEABLE
42         },
43         {
44                 .name           = "params-onenand",
45                 .offset         = MTDPART_OFS_APPEND,
46                 .size           = 1*(64*2048),
47         },
48         {
49                 .name           = "linux-onenand",
50                 .offset         = MTDPART_OFS_APPEND,
51                 .size           = 40*(64*2048),
52         },
53         {
54                 .name           = "jffs2-onenand",
55                 .offset         = MTDPART_OFS_APPEND,
56                 .size           = MTDPART_SIZ_FULL,
57         },
58 };
59
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 */
65 };
66
67 static struct platform_device omap3evm_onenand_device = {
68         .name           = "omap2-onenand",
69         .id             = -1,
70         .dev = {
71                 .platform_data = &omap3evm_onenand_data,
72         },
73 };
74
75 static struct mtd_partition omap3evm_nand_partitions[] = {
76         /* All the partition sizes are listed in terms of NAND block size */
77         {
78                 .name           = "xloader-nand",
79                 .offset         = 0,
80                 .size           = 4*(128 * 1024),
81                 .mask_flags     = MTD_WRITEABLE
82         },
83         {
84                 .name           = "uboot-nand",
85                 .offset         = MTDPART_OFS_APPEND,
86                 .size           = 14*(128 * 1024),
87                 .mask_flags     = MTD_WRITEABLE
88         },
89         {
90                 .name           = "params-nand",
91
92                 .offset         = MTDPART_OFS_APPEND,
93                 .size           = 2*(128 * 1024)
94         },
95         {
96                 .name           = "linux-nand",
97                 .offset         = MTDPART_OFS_APPEND,
98                 .size           = 40*(128 * 1024)
99         },
100         {
101                 .name           = "jffs2-nand",
102                 .size           = MTDPART_SIZ_FULL,
103                 .offset         = MTDPART_OFS_APPEND,
104         },
105 };
106
107 static struct omap_nand_platform_data omap3evm_nand_data = {
108         .parts          = omap3evm_nand_partitions,
109         .nr_parts       = ARRAY_SIZE(omap3evm_nand_partitions),
110         .nand_setup     = NULL,
111         .dma_channel    = -1,           /* disable DMA in OMAP NAND driver */
112         .dev_ready      = NULL,
113 };
114
115 static struct resource omap3evm_nand_resource = {
116         .flags          = IORESOURCE_MEM,
117 };
118
119 static struct platform_device omap3evm_nand_device = {
120         .name           = "omap2-nand",
121         .id             = 0,
122         .dev            = {
123                 .platform_data  = &omap3evm_nand_data,
124         },
125         .num_resources  = 1,
126         .resource       = &omap3evm_nand_resource,
127 };
128
129 /*
130  *      omap3evm_onenand_setup - Set the onenand sync mode
131  *      @onenand_base:  The onenand base address in GPMC memory map
132  *
133  */
134
135 static int omap3evm_onenand_setup(void __iomem *onenand_base, int freq)
136 {
137         /* nothing is required to be setup for onenand as of now */
138         return 0;
139 }
140
141 void __init omap3evm_flash_init(void)
142 {
143         u8              cs = 0;
144         u8              onenandcs = GPMC_CS_NUM + 1, nandcs = GPMC_CS_NUM + 1;
145         u32             gpmc_base_add = OMAP34XX_GPMC_VIRT;
146
147         while (cs < GPMC_CS_NUM) {
148                 u32 ret = 0;
149                 ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
150
151                 /*
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
157                 */
158                 if ((ret & 0xC00) == 0x800) {
159                         /* Found it!! */
160                         if (nandcs > GPMC_CS_NUM)
161                                 nandcs = cs;
162                 } else {
163                         ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
164                         if ((ret & 0x3F) == (ONENAND_MAP >> 24))
165                                 onenandcs = cs;
166                 }
167                 cs++;
168         }
169         if ((nandcs > GPMC_CS_NUM) && (onenandcs > GPMC_CS_NUM)) {
170                 printk(KERN_INFO "NAND/OneNAND: Unable to find configuration "
171                                 " in GPMC\n ");
172                 return;
173         }
174
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);
180
181                 if (platform_device_register(&omap3evm_nand_device) < 0) {
182                         printk(KERN_ERR "Unable to register NAND device\n");
183                 }
184         }
185
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");
190         }
191 }
192