Linux 2.6.31-rc6
[linux-2.6] / arch / avr32 / boards / merisc / flash.c
1 /*
2  * Merisc board-specific flash initialization
3  *
4  * Copyright (C) 2008 Martinsson Elektronik AB
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 #include <linux/init.h>
11 #include <linux/platform_device.h>
12 #include <linux/mtd/mtd.h>
13 #include <linux/mtd/partitions.h>
14 #include <linux/mtd/physmap.h>
15 #include <mach/smc.h>
16
17 /* Will be translated to units of 14.3 ns, rounded up */
18 static struct smc_timing flash_timing __initdata = {
19         .ncs_read_setup         = 1 * 14,
20         .nrd_setup              = 5 * 14,
21         .ncs_write_setup        = 1 * 14,
22         .nwe_setup              = 2 * 14,
23
24         .ncs_read_pulse         = 12 * 14,
25         .nrd_pulse              = 7 * 14,
26         .ncs_write_pulse        = 8 * 14,
27         .nwe_pulse              = 4 * 14,
28
29         .read_cycle             = 14 * 14,
30         .write_cycle            = 10 * 14,
31 };
32
33 static struct smc_config flash_config __initdata = {
34         .bus_width      = 2,
35         .nrd_controlled = 1,
36         .nwe_controlled = 1,
37         .byte_write     = 1,
38         .tdf_cycles     = 3,
39 };
40
41 static struct mtd_partition flash_0_parts[] = {
42         {
43                 .name           = "boot",
44                 .offset         = 0x00000000,
45                 .size           = 0x00060000,
46                 .mask_flags     = 0,
47         },
48         {
49                 .name           = "kernel",
50                 .offset         = 0x00060000,
51                 .size           = 0x00200000,
52                 .mask_flags     = 0,
53         },
54         {
55                 .name           = "root",
56                 .offset         = 0x00260000,
57                 .size           = MTDPART_SIZ_FULL,
58                 .mask_flags     = 0,
59         },
60 };
61
62 static struct mtd_partition flash_1_parts[] = {
63         {
64                 .name           = "2ndflash",
65                 .offset         = 0x00000000,
66                 .size           = MTDPART_SIZ_FULL,
67                 .mask_flags     = 0,
68         },
69 };
70
71 static struct physmap_flash_data flash_data[] = {
72         {
73                 .width          = 2,
74                 .nr_parts       = ARRAY_SIZE(flash_0_parts),
75                 .parts          = flash_0_parts,
76         },
77         {
78                 .width          = 2,
79                 .nr_parts       = ARRAY_SIZE(flash_1_parts),
80                 .parts          = flash_1_parts,
81         }
82 };
83
84 static struct resource flash_resource[] = {
85         {
86                 .start          = 0x00000000,
87                 .end            = 0x03ffffff,
88                 .flags          = IORESOURCE_MEM,
89         },
90         {
91                 .start          = 0x04000000,
92                 .end            = 0x07ffffff,
93                 .flags          = IORESOURCE_MEM,
94         },
95 };
96
97 static struct platform_device flash_device[] = {
98         {
99                 .name           = "physmap-flash",
100                 .id             = 0,
101                 .resource       = &flash_resource[0],
102                 .num_resources  = 1,
103                 .dev            = {
104                         .platform_data  = &flash_data[0],
105                 },
106         },
107         {
108                 .name           = "physmap-flash",
109                 .id             = 1,
110                 .resource       = &flash_resource[1],
111                 .num_resources  = 1,
112                 .dev            = {
113                         .platform_data  = &flash_data[1],
114                 },
115         },
116 };
117
118 static int __init merisc_flash_init(void)
119 {
120         int ret;
121         smc_set_timing(&flash_config, &flash_timing);
122
123         ret = smc_set_configuration(0, &flash_config);
124         if (ret < 0) {
125                 printk(KERN_ERR "Merisc: failed to set NOR flash timing #0\n");
126                 return ret;
127         }
128
129         ret = smc_set_configuration(4, &flash_config);
130         if (ret < 0) {
131                 printk(KERN_ERR "Merisc: failed to set NOR flash timing #1\n");
132                 return ret;
133         }
134
135         platform_device_register(&flash_device[0]);
136         platform_device_register(&flash_device[1]);
137         return 0;
138 }
139 device_initcall(merisc_flash_init);