Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
flash.c
Go to the documentation of this file.
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);