diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/arm/mach-integrator/integrator_ap.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/arm/mach-integrator/integrator_ap.c')
-rw-r--r-- | arch/arm/mach-integrator/integrator_ap.c | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c new file mode 100644 index 000000000000..91ba9fd79c87 --- /dev/null +++ b/arch/arm/mach-integrator/integrator_ap.c | |||
@@ -0,0 +1,302 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-integrator/integrator_ap.c | ||
3 | * | ||
4 | * Copyright (C) 2000-2003 Deep Blue Solutions Ltd | ||
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 as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/list.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/string.h> | ||
27 | #include <linux/sysdev.h> | ||
28 | |||
29 | #include <asm/hardware.h> | ||
30 | #include <asm/io.h> | ||
31 | #include <asm/irq.h> | ||
32 | #include <asm/setup.h> | ||
33 | #include <asm/mach-types.h> | ||
34 | #include <asm/hardware/amba.h> | ||
35 | #include <asm/hardware/amba_kmi.h> | ||
36 | |||
37 | #include <asm/arch/lm.h> | ||
38 | |||
39 | #include <asm/mach/arch.h> | ||
40 | #include <asm/mach/flash.h> | ||
41 | #include <asm/mach/irq.h> | ||
42 | #include <asm/mach/map.h> | ||
43 | #include <asm/mach/time.h> | ||
44 | |||
45 | #include "common.h" | ||
46 | |||
47 | /* | ||
48 | * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx | ||
49 | * is the (PA >> 12). | ||
50 | * | ||
51 | * Setup a VA for the Integrator interrupt controller (for header #0, | ||
52 | * just for now). | ||
53 | */ | ||
54 | #define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) | ||
55 | #define VA_SC_BASE IO_ADDRESS(INTEGRATOR_SC_BASE) | ||
56 | #define VA_EBI_BASE IO_ADDRESS(INTEGRATOR_EBI_BASE) | ||
57 | #define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET | ||
58 | |||
59 | /* | ||
60 | * Logical Physical | ||
61 | * e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M) | ||
62 | * ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M) | ||
63 | * ed000000 62000000 PCI V3 regs PHYS_PCI_V3_BASE (max 64k) | ||
64 | * ee000000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M) | ||
65 | * ef000000 Cache flush | ||
66 | * f1000000 10000000 Core module registers | ||
67 | * f1100000 11000000 System controller registers | ||
68 | * f1200000 12000000 EBI registers | ||
69 | * f1300000 13000000 Counter/Timer | ||
70 | * f1400000 14000000 Interrupt controller | ||
71 | * f1600000 16000000 UART 0 | ||
72 | * f1700000 17000000 UART 1 | ||
73 | * f1a00000 1a000000 Debug LEDs | ||
74 | * f1b00000 1b000000 GPIO | ||
75 | */ | ||
76 | |||
77 | static struct map_desc ap_io_desc[] __initdata = { | ||
78 | { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K, MT_DEVICE }, | ||
79 | { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K, MT_DEVICE }, | ||
80 | { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K, MT_DEVICE }, | ||
81 | { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K, MT_DEVICE }, | ||
82 | { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K, MT_DEVICE }, | ||
83 | { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K, MT_DEVICE }, | ||
84 | { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE }, | ||
85 | { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE }, | ||
86 | { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE }, | ||
87 | { PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M, MT_DEVICE }, | ||
88 | { PCI_CONFIG_VADDR, PHYS_PCI_CONFIG_BASE, SZ_16M, MT_DEVICE }, | ||
89 | { PCI_V3_VADDR, PHYS_PCI_V3_BASE, SZ_64K, MT_DEVICE }, | ||
90 | { PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K, MT_DEVICE } | ||
91 | }; | ||
92 | |||
93 | static void __init ap_map_io(void) | ||
94 | { | ||
95 | iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc)); | ||
96 | } | ||
97 | |||
98 | #define INTEGRATOR_SC_VALID_INT 0x003fffff | ||
99 | |||
100 | static void sc_mask_irq(unsigned int irq) | ||
101 | { | ||
102 | writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR); | ||
103 | } | ||
104 | |||
105 | static void sc_unmask_irq(unsigned int irq) | ||
106 | { | ||
107 | writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET); | ||
108 | } | ||
109 | |||
110 | static struct irqchip sc_chip = { | ||
111 | .ack = sc_mask_irq, | ||
112 | .mask = sc_mask_irq, | ||
113 | .unmask = sc_unmask_irq, | ||
114 | }; | ||
115 | |||
116 | static void __init ap_init_irq(void) | ||
117 | { | ||
118 | unsigned int i; | ||
119 | |||
120 | /* Disable all interrupts initially. */ | ||
121 | /* Do the core module ones */ | ||
122 | writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); | ||
123 | |||
124 | /* do the header card stuff next */ | ||
125 | writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); | ||
126 | writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); | ||
127 | |||
128 | for (i = 0; i < NR_IRQS; i++) { | ||
129 | if (((1 << i) & INTEGRATOR_SC_VALID_INT) != 0) { | ||
130 | set_irq_chip(i, &sc_chip); | ||
131 | set_irq_handler(i, do_level_IRQ); | ||
132 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | |||
137 | #ifdef CONFIG_PM | ||
138 | static unsigned long ic_irq_enable; | ||
139 | |||
140 | static int irq_suspend(struct sys_device *dev, pm_message_t state) | ||
141 | { | ||
142 | ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE); | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static int irq_resume(struct sys_device *dev) | ||
147 | { | ||
148 | /* disable all irq sources */ | ||
149 | writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); | ||
150 | writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); | ||
151 | writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); | ||
152 | |||
153 | writel(ic_irq_enable, VA_IC_BASE + IRQ_ENABLE_SET); | ||
154 | return 0; | ||
155 | } | ||
156 | #else | ||
157 | #define irq_suspend NULL | ||
158 | #define irq_resume NULL | ||
159 | #endif | ||
160 | |||
161 | static struct sysdev_class irq_class = { | ||
162 | set_kset_name("irq"), | ||
163 | .suspend = irq_suspend, | ||
164 | .resume = irq_resume, | ||
165 | }; | ||
166 | |||
167 | static struct sys_device irq_device = { | ||
168 | .id = 0, | ||
169 | .cls = &irq_class, | ||
170 | }; | ||
171 | |||
172 | static int __init irq_init_sysfs(void) | ||
173 | { | ||
174 | int ret = sysdev_class_register(&irq_class); | ||
175 | if (ret == 0) | ||
176 | ret = sysdev_register(&irq_device); | ||
177 | return ret; | ||
178 | } | ||
179 | |||
180 | device_initcall(irq_init_sysfs); | ||
181 | |||
182 | /* | ||
183 | * Flash handling. | ||
184 | */ | ||
185 | #define SC_CTRLC (VA_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET) | ||
186 | #define SC_CTRLS (VA_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET) | ||
187 | #define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET) | ||
188 | #define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET) | ||
189 | |||
190 | static int ap_flash_init(void) | ||
191 | { | ||
192 | u32 tmp; | ||
193 | |||
194 | writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); | ||
195 | |||
196 | tmp = readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE; | ||
197 | writel(tmp, EBI_CSR1); | ||
198 | |||
199 | if (!(readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) { | ||
200 | writel(0xa05f, EBI_LOCK); | ||
201 | writel(tmp, EBI_CSR1); | ||
202 | writel(0, EBI_LOCK); | ||
203 | } | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static void ap_flash_exit(void) | ||
208 | { | ||
209 | u32 tmp; | ||
210 | |||
211 | writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); | ||
212 | |||
213 | tmp = readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE; | ||
214 | writel(tmp, EBI_CSR1); | ||
215 | |||
216 | if (readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) { | ||
217 | writel(0xa05f, EBI_LOCK); | ||
218 | writel(tmp, EBI_CSR1); | ||
219 | writel(0, EBI_LOCK); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | static void ap_flash_set_vpp(int on) | ||
224 | { | ||
225 | unsigned long reg = on ? SC_CTRLS : SC_CTRLC; | ||
226 | |||
227 | writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg); | ||
228 | } | ||
229 | |||
230 | static struct flash_platform_data ap_flash_data = { | ||
231 | .map_name = "cfi_probe", | ||
232 | .width = 4, | ||
233 | .init = ap_flash_init, | ||
234 | .exit = ap_flash_exit, | ||
235 | .set_vpp = ap_flash_set_vpp, | ||
236 | }; | ||
237 | |||
238 | static struct resource cfi_flash_resource = { | ||
239 | .start = INTEGRATOR_FLASH_BASE, | ||
240 | .end = INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1, | ||
241 | .flags = IORESOURCE_MEM, | ||
242 | }; | ||
243 | |||
244 | static struct platform_device cfi_flash_device = { | ||
245 | .name = "armflash", | ||
246 | .id = 0, | ||
247 | .dev = { | ||
248 | .platform_data = &ap_flash_data, | ||
249 | }, | ||
250 | .num_resources = 1, | ||
251 | .resource = &cfi_flash_resource, | ||
252 | }; | ||
253 | |||
254 | static void __init ap_init(void) | ||
255 | { | ||
256 | unsigned long sc_dec; | ||
257 | int i; | ||
258 | |||
259 | platform_device_register(&cfi_flash_device); | ||
260 | |||
261 | sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); | ||
262 | for (i = 0; i < 4; i++) { | ||
263 | struct lm_device *lmdev; | ||
264 | |||
265 | if ((sc_dec & (16 << i)) == 0) | ||
266 | continue; | ||
267 | |||
268 | lmdev = kmalloc(sizeof(struct lm_device), GFP_KERNEL); | ||
269 | if (!lmdev) | ||
270 | continue; | ||
271 | |||
272 | memset(lmdev, 0, sizeof(struct lm_device)); | ||
273 | |||
274 | lmdev->resource.start = 0xc0000000 + 0x10000000 * i; | ||
275 | lmdev->resource.end = lmdev->resource.start + 0x0fffffff; | ||
276 | lmdev->resource.flags = IORESOURCE_MEM; | ||
277 | lmdev->irq = IRQ_AP_EXPINT0 + i; | ||
278 | lmdev->id = i; | ||
279 | |||
280 | lm_device_register(lmdev); | ||
281 | } | ||
282 | } | ||
283 | |||
284 | static void __init ap_init_timer(void) | ||
285 | { | ||
286 | integrator_time_init(1000000 * TICKS_PER_uSEC / HZ, 0); | ||
287 | } | ||
288 | |||
289 | static struct sys_timer ap_timer = { | ||
290 | .init = ap_init_timer, | ||
291 | .offset = integrator_gettimeoffset, | ||
292 | }; | ||
293 | |||
294 | MACHINE_START(INTEGRATOR, "ARM-Integrator") | ||
295 | MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") | ||
296 | BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) | ||
297 | BOOT_PARAMS(0x00000100) | ||
298 | MAPIO(ap_map_io) | ||
299 | INITIRQ(ap_init_irq) | ||
300 | .timer = &ap_timer, | ||
301 | INIT_MACHINE(ap_init) | ||
302 | MACHINE_END | ||