]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/board-2430sdp-flash.c
Merge branch 'omap-fixes'
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / board-2430sdp-flash.c
1 /*
2  * linux/arch/arm/mach-omap2/board-2430sdp-flash.c
3  *
4  * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
5  * Author: Kevin Hilman
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11
12 #include <linux/kernel.h>
13 #include <linux/platform_device.h>
14 #include <asm/mach/flash.h>
15 #include <linux/mtd/mtd.h>
16 #include <linux/mtd/partitions.h>
17 #include <linux/mtd/onenand_regs.h>
18
19 #include <asm/io.h>
20 #include <mach/onenand.h>
21 #include <mach/board.h>
22 #include <mach/gpmc.h>
23 #include <mach/nand.h>
24
25 #define ONENAND_MAP 0x20000000
26 #define GPMC_OFF_CONFIG1_0 0x60
27
28 enum fstype {
29         NAND = 0,
30         NOR,
31         ONENAND,
32         UNKNOWN = -1
33 };
34
35 static enum fstype flash_type = NAND;
36
37 static struct mtd_partition nand_partitions[] = {
38         {
39                 .name           = "X-Loader",
40                 .offset         = 0,
41                 .size           = 4*(64*2048),  /* 0-3 blks reserved.
42                                                    Mandated by ROM code */
43                 .mask_flags     = MTD_WRITEABLE /* force read-only */
44         },
45         {
46                 .name           = "U-Boot",
47                 .offset         = MTDPART_OFS_APPEND,
48                 .size           =  4*(64*2048),
49                 .mask_flags     = MTD_WRITEABLE /* force read-only */
50         },
51         {
52                 .name           = "U-Boot Environment",
53                 .offset         = MTDPART_OFS_APPEND,
54                 .size           = 2*(64*2048),
55         },
56         {
57                 .name           = "Kernel",
58                 .offset         = MTDPART_OFS_APPEND,
59                 .size           = 32*(64*2048),         /* 4*1M */
60         },
61         {
62                 .name           = "File System",
63                 .offset         = MTDPART_OFS_APPEND,
64                 .size           = MTDPART_SIZ_FULL,
65         },
66 };
67 static struct omap_nand_platform_data sdp_nand_data = {
68         .parts          = nand_partitions,
69         .nr_parts       = ARRAY_SIZE(nand_partitions),
70         .dma_channel    = -1,   /* disable DMA in OMAP OneNAND driver */
71 };
72
73 static struct platform_device sdp_nand_device = {
74         .name           = "omap2-nand",
75         .id             = -1,
76         .dev = {
77                 .platform_data = &sdp_nand_data,
78         },
79 };
80
81 static struct mtd_partition onenand_partitions[] = {
82         {
83                 .name           = "(OneNAND)X-Loader",
84                 .offset         = 0,
85                 .size           = 4*(64*2048),  /* 0-3 blks reserved.
86                                                    Mandated by ROM code */
87                 .mask_flags     = MTD_WRITEABLE /* force read-only */
88         },
89         {
90                 .name           = "(OneNAND)U-Boot",
91                 .offset         = MTDPART_OFS_APPEND,
92                 .size           =  2*(64*2048),
93                 .mask_flags     = MTD_WRITEABLE /* force read-only */
94         },
95         {
96                 .name           = "(OneNAND)U-Boot Environment",
97                 .offset         = MTDPART_OFS_APPEND,
98                 .size           = 1*(64*2048),
99         },
100         {
101                 .name           = "(OneNAND)Kernel",
102                 .offset         = MTDPART_OFS_APPEND,
103                 .size           = 4*(64*2048),
104         },
105         {
106                 .name           = "(OneNAND)File System",
107                 .offset         = MTDPART_OFS_APPEND,
108                 .size           = MTDPART_SIZ_FULL,
109         },
110 };
111
112 static struct omap_onenand_platform_data sdp_onenand_data = {
113         .parts          = onenand_partitions,
114         .nr_parts       = ARRAY_SIZE(onenand_partitions),
115         .dma_channel    = -1,   /* disable DMA in OMAP OneNAND driver */
116 };
117
118 static struct platform_device sdp_onenand_device = {
119         .name           = "omap2-onenand",
120         .id             = -1,
121         .dev = {
122                 .platform_data = &sdp_onenand_data,
123         },
124 };
125
126 void __init sdp2430_flash_init(void)
127 {
128         void __iomem *gpmc_base_add, *gpmc_cs_base_add;
129         unsigned char cs = 0;
130
131         gpmc_base_add = (__force void __iomem *)OMAP243X_GPMC_VIRT;
132         while (cs < GPMC_CS_NUM) {
133                 int ret = 0;
134
135                 /* Each GPMC set for a single CS is at offset 0x30 */
136                 gpmc_cs_base_add = (gpmc_base_add + GPMC_OFF_CONFIG1_0 +
137                                     (cs*0x30));
138
139                 /* xloader/Uboot would have programmed the NAND/oneNAND
140                  * base address for us This is a ugly hack. The proper
141                  * way of doing this is to pass the setup of u-boot up
142                  * to kernel using kernel params - something on the
143                  * lines of machineID. Check if Nand/oneNAND is
144                  * configured */
145                 ret = __raw_readl(gpmc_cs_base_add + GPMC_CS_CONFIG1);
146                 if ((ret & 0xC00) == (0x800)) {
147                         /* Found it!! */
148                         printk(KERN_INFO "NAND: Found NAND on CS %d \n", cs);
149                         flash_type = NAND;
150                         break;
151                 }
152                 ret = __raw_readl(gpmc_cs_base_add + GPMC_CS_CONFIG7);
153                 if ((ret & 0x3F) == (ONENAND_MAP >> 24)) {
154                         /* Found it!! */
155                         flash_type = ONENAND;
156                         break;
157                 }
158                 cs++;
159         }
160         if (cs >= GPMC_CS_NUM) {
161                 printk(KERN_INFO "MTD: Unable to find MTD configuration in "
162                                  "GPMC   - not registering.\n");
163                 return;
164         }
165
166         if (flash_type == NAND) {
167                 sdp_nand_data.cs               = cs;
168                 sdp_nand_data.gpmc_cs_baseaddr = gpmc_cs_base_add;
169                 sdp_nand_data.gpmc_baseaddr    = gpmc_base_add;
170
171                 if (platform_device_register(&sdp_nand_device) < 0) {
172                         printk(KERN_ERR "Unable to register NAND device\n");
173                         return;
174                 }
175         }
176
177         if (flash_type == ONENAND) {
178                 sdp_onenand_data.cs = cs;
179
180                 if (platform_device_register(&sdp_onenand_device) < 0) {
181                         printk(KERN_ERR "Unable to register OneNAND device\n");
182                         return;
183                 }
184         }
185 }