4e1beaae3825ce32811945fe8617d48a5191403b
[openwrt/staging/dedeckeh.git] / target / linux / atheros-2.6 / files / arch / mips / atheros / ar5312.c
1 /*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
7 * Copyright (C) 2006 FON Technology, SL.
8 * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
9 * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
10 */
11
12 /*
13 * Platform devices for Atheros SoCs
14 */
15
16 #include <linux/autoconf.h>
17 #include <linux/init.h>
18 #include <linux/module.h>
19 #include <linux/types.h>
20 #include <linux/string.h>
21 #include <linux/mtd/physmap.h>
22 #include <linux/platform_device.h>
23 #include <linux/kernel.h>
24 #include <linux/reboot.h>
25 #include <asm/bootinfo.h>
26 #include <asm/reboot.h>
27 #include <asm/time.h>
28 #include <asm/irq.h>
29 #include <asm/io.h>
30 #include "ar531x.h"
31
32
33
34 static struct platform_device *ar5312_devs[5];
35
36 static struct resource ar5312_eth0_res[] = {
37 {
38 .name = "eth_membase",
39 .flags = IORESOURCE_MEM,
40 .start = KSEG1ADDR(AR531X_ENET0),
41 .end = KSEG1ADDR(AR531X_ENET0 + 0x2000),
42 },
43 {
44 .name = "eth_irq",
45 .flags = IORESOURCE_IRQ,
46 .start = AR5312_IRQ_ENET0_INTRS,
47 .end = AR5312_IRQ_ENET0_INTRS,
48 },
49 };
50
51
52 static struct resource ar5312_eth1_res[] = {
53 {
54 .name = "eth_membase",
55 .flags = IORESOURCE_MEM,
56 .start = KSEG1ADDR(AR531X_ENET1),
57 .end = KSEG1ADDR(AR531X_ENET1 + 0x2000),
58 },
59 {
60 .name = "eth_irq",
61 .flags = IORESOURCE_IRQ,
62 .start = AR5312_IRQ_ENET1_INTRS,
63 .end = AR5312_IRQ_ENET1_INTRS,
64 },
65 };
66
67
68 static struct ar531x_eth ar5312_eth0_data = {
69 .phy = 0x1f,
70 .mac = 0,
71 .reset_base = AR531X_RESET,
72 .reset_mac = AR531X_RESET_ENET0,
73 .reset_phy = AR531X_RESET_EPHY0,
74 };
75
76 static struct ar531x_eth ar5312_eth1_data = {
77 .phy = 0,
78 .mac = 1,
79 .reset_base = AR531X_RESET,
80 .reset_mac = AR531X_RESET_ENET1,
81 .reset_phy = AR531X_RESET_EPHY1,
82 };
83
84 static struct platform_device ar5312_eth[] = {
85 {
86 .id = 0,
87 .name = "ar531x-eth",
88 .dev.platform_data = &ar5312_eth0_data,
89 .resource = ar5312_eth0_res,
90 .num_resources = ARRAY_SIZE(ar5312_eth0_res)
91 },
92 {
93 .id = 1,
94 .name = "ar531x-eth",
95 .dev.platform_data = &ar5312_eth1_data,
96 .resource = ar5312_eth1_res,
97 .num_resources = ARRAY_SIZE(ar5312_eth1_res)
98 },
99 };
100
101 static struct platform_device ar5312_wmac[] = {
102 {
103 .id = 0,
104 .name = "ar531x-wmac",
105 },
106 {
107 .id = 1,
108 .name = "ar531x-wmac",
109 },
110 };
111
112
113 static struct physmap_flash_data ar5312_flash_data = {
114 .width = 2,
115 };
116
117 static struct resource ar5312_flash_resource = {
118 .start = AR531X_FLASH,
119 .end = AR531X_FLASH + 0x400000 - 1,
120 .flags = IORESOURCE_MEM,
121 };
122
123 static struct platform_device ar5312_physmap_flash = {
124 .name = "physmap-flash",
125 .id = 0,
126 .dev = {
127 .platform_data = &ar5312_flash_data,
128 },
129 .num_resources = 1,
130 .resource = &ar5312_flash_resource,
131 };
132
133
134 /*
135 * NB: This mapping size is larger than the actual flash size,
136 * but this shouldn't be a problem here, because the flash
137 * will simply be mapped multiple times.
138 */
139 static char __init *ar5312_flash_limit(void)
140 {
141 u32 ctl;
142 /* Configure flash bank 0 */
143 ctl = FLASHCTL_E |
144 FLASHCTL_AC_8M |
145 FLASHCTL_RBLE |
146 (0x01 << FLASHCTL_IDCY_S) |
147 (0x07 << FLASHCTL_WST1_S) |
148 (0x07 << FLASHCTL_WST2_S) |
149 (sysRegRead(AR531X_FLASHCTL0) & FLASHCTL_MW);
150
151 sysRegWrite(AR531X_FLASHCTL0, ctl);
152
153 /* Disable other flash banks */
154 sysRegWrite(AR531X_FLASHCTL1,
155 sysRegRead(AR531X_FLASHCTL1) & ~(FLASHCTL_E | FLASHCTL_AC));
156
157 sysRegWrite(AR531X_FLASHCTL2,
158 sysRegRead(AR531X_FLASHCTL2) & ~(FLASHCTL_E | FLASHCTL_AC));
159
160 return (char *) KSEG1ADDR(AR531X_FLASH + 0x400000);
161 }
162
163 static struct ar531x_config __init *init_wmac(int unit)
164 {
165 struct ar531x_config *config;
166
167 config = (struct ar531x_config *) kzalloc(sizeof(struct ar531x_config), GFP_KERNEL);
168 config->board = board_config;
169 config->radio = radio_config;
170 config->unit = unit;
171 config->tag = (u_int16_t) ((sysRegRead(AR531X_REV) >> AR531X_REV_WMAC_MIN_S) & AR531X_REV_CHIP);
172
173 return config;
174 }
175
176 int __init ar5312_init_devices(void)
177 {
178 char *radio;
179 int dev = 0;
180
181 if (mips_machtype != MACH_ATHEROS_AR5312)
182 return 0;
183
184 ar531x_find_config(ar5312_flash_limit());
185 ar5312_eth0_data.board_config = board_config;
186 ar5312_eth1_data.board_config = board_config;
187 ar5312_devs[dev++] = &ar5312_physmap_flash;
188 ar5312_devs[dev++] = &ar5312_eth[0];
189 ar5312_devs[dev++] = &ar5312_eth[1];
190
191 radio = radio_config + AR531X_RADIO_MASK_OFF;
192 if (*((u32 *) radio) & AR531X_RADIO0_MASK) {
193 ar5312_wmac[0].dev.platform_data = init_wmac(0);
194 ar5312_devs[dev++] = &ar5312_wmac[0];
195 }
196 if (*((u32 *) radio) & AR531X_RADIO1_MASK) {
197 ar5312_wmac[1].dev.platform_data = init_wmac(1);
198 ar5312_devs[dev++] = &ar5312_wmac[1];
199 }
200
201 return platform_add_devices(ar5312_devs, dev);
202 }
203
204
205 /*
206 * Called when an interrupt is received, this function
207 * determines exactly which interrupt it was, and it
208 * invokes the appropriate handler.
209 *
210 * Implicitly, we also define interrupt priority by
211 * choosing which to dispatch first.
212 */
213 asmlinkage void ar5312_irq_dispatch(void)
214 {
215 int pending = read_c0_status() & read_c0_cause();
216
217 if (pending & CAUSEF_IP2)
218 do_IRQ(AR5312_IRQ_WLAN0_INTRS);
219 else if (pending & CAUSEF_IP3)
220 do_IRQ(AR5312_IRQ_ENET0_INTRS);
221 else if (pending & CAUSEF_IP4)
222 do_IRQ(AR5312_IRQ_ENET1_INTRS);
223 else if (pending & CAUSEF_IP5)
224 do_IRQ(AR5312_IRQ_WLAN1_INTRS);
225 else if (pending & CAUSEF_IP6) {
226 unsigned int ar531x_misc_intrs = sysRegRead(AR531X_ISR) & sysRegRead(AR531X_IMR);
227
228 if (ar531x_misc_intrs & AR531X_ISR_TIMER) {
229 do_IRQ(AR531X_MISC_IRQ_TIMER);
230 (void)sysRegRead(AR531X_TIMER);
231 } else if (ar531x_misc_intrs & AR531X_ISR_AHBPROC)
232 do_IRQ(AR531X_MISC_IRQ_AHB_PROC);
233 else if ((ar531x_misc_intrs & AR531X_ISR_UART0))
234 do_IRQ(AR531X_MISC_IRQ_UART0);
235 else if (ar531x_misc_intrs & AR531X_ISR_WD)
236 do_IRQ(AR531X_MISC_IRQ_WATCHDOG);
237 else
238 do_IRQ(AR531X_MISC_IRQ_NONE);
239 } else if (pending & CAUSEF_IP7) {
240 do_IRQ(AR531X_IRQ_CPU_CLOCK);
241 }
242 else
243 do_IRQ(AR531X_IRQ_NONE);
244 }
245
246 static void ar5312_halt(void)
247 {
248 while (1);
249 }
250
251 static void ar5312_power_off(void)
252 {
253 ar5312_halt();
254 }
255
256
257 static void ar5312_restart(char *command)
258 {
259 /* reset the system */
260 for(;;) sysRegWrite(AR531X_RESET, AR531X_RESET_SYSTEM);
261 }
262
263
264 /*
265 * This table is indexed by bits 5..4 of the CLOCKCTL1 register
266 * to determine the predevisor value.
267 */
268 static int __initdata CLOCKCTL1_PREDIVIDE_TABLE[4] = {
269 1,
270 2,
271 4,
272 5
273 };
274
275
276 static unsigned int __init ar5312_cpu_frequency(void)
277 {
278 unsigned int result;
279 unsigned int predivide_mask, predivide_shift;
280 unsigned int multiplier_mask, multiplier_shift;
281 unsigned int clockCtl1, preDivideSelect, preDivisor, multiplier;
282 unsigned int doubler_mask;
283 unsigned int wisoc_revision;
284
285 /* Trust the bootrom's idea of cpu frequency. */
286 if ((result = sysRegRead(AR5312_SCRATCH)))
287 return result;
288
289 wisoc_revision = (sysRegRead(AR531X_REV) & AR531X_REV_MAJ) >> AR531X_REV_MAJ_S;
290 if (wisoc_revision == AR531X_REV_MAJ_AR2313) {
291 predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK;
292 predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT;
293 multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK;
294 multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT;
295 doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK;
296 } else { /* AR5312 and AR2312 */
297 predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK;
298 predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT;
299 multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK;
300 multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT;
301 doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK;
302 }
303
304 /*
305 * Clocking is derived from a fixed 40MHz input clock.
306 *
307 * cpuFreq = InputClock * MULT (where MULT is PLL multiplier)
308 * sysFreq = cpuFreq / 4 (used for APB clock, serial,
309 * flash, Timer, Watchdog Timer)
310 *
311 * cntFreq = cpuFreq / 2 (use for CPU count/compare)
312 *
313 * So, for example, with a PLL multiplier of 5, we have
314 *
315 * cpuFreq = 200MHz
316 * sysFreq = 50MHz
317 * cntFreq = 100MHz
318 *
319 * We compute the CPU frequency, based on PLL settings.
320 */
321
322 clockCtl1 = sysRegRead(AR5312_CLOCKCTL1);
323 preDivideSelect = (clockCtl1 & predivide_mask) >> predivide_shift;
324 preDivisor = CLOCKCTL1_PREDIVIDE_TABLE[preDivideSelect];
325 multiplier = (clockCtl1 & multiplier_mask) >> multiplier_shift;
326
327 if (clockCtl1 & doubler_mask) {
328 multiplier = multiplier << 1;
329 }
330 return (40000000 / preDivisor) * multiplier;
331 }
332
333 static inline int ar5312_sys_frequency(void)
334 {
335 return ar5312_cpu_frequency() / 4;
336 }
337
338 static void __init ar5312_time_init(void)
339 {
340 mips_hpt_frequency = ar5312_cpu_frequency() / 2;
341 }
342
343
344 /* Enable the specified AR531X_MISC_IRQ interrupt */
345 static void
346 ar5312_misc_intr_enable(unsigned int irq)
347 {
348 unsigned int imr;
349
350 imr = sysRegRead(AR531X_IMR);
351 imr |= (1 << (irq - AR531X_MISC_IRQ_BASE - 1));
352 sysRegWrite(AR531X_IMR, imr);
353 sysRegRead(AR531X_IMR); /* flush write buffer */
354 }
355
356 /* Disable the specified AR531X_MISC_IRQ interrupt */
357 static void
358 ar5312_misc_intr_disable(unsigned int irq)
359 {
360 unsigned int imr;
361
362 imr = sysRegRead(AR531X_IMR);
363 imr &= ~(1 << (irq - AR531X_MISC_IRQ_BASE - 1));
364 sysRegWrite(AR531X_IMR, imr);
365 sysRegRead(AR531X_IMR); /* flush write buffer */
366 }
367
368 /* Turn on the specified AR531X_MISC_IRQ interrupt */
369 static unsigned int
370 ar5312_misc_intr_startup(unsigned int irq)
371 {
372 ar5312_misc_intr_enable(irq);
373 return 0;
374 }
375
376 /* Turn off the specified AR531X_MISC_IRQ interrupt */
377 static void
378 ar5312_misc_intr_shutdown(unsigned int irq)
379 {
380 ar5312_misc_intr_disable(irq);
381 }
382
383 static void
384 ar5312_misc_intr_ack(unsigned int irq)
385 {
386 ar5312_misc_intr_disable(irq);
387 }
388
389 static void
390 ar5312_misc_intr_end(unsigned int irq)
391 {
392 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
393 ar5312_misc_intr_enable(irq);
394 }
395
396 static struct irq_chip ar5312_misc_intr_controller = {
397 .typename = "AR5312 misc",
398 .startup = ar5312_misc_intr_startup,
399 .shutdown = ar5312_misc_intr_shutdown,
400 .enable = ar5312_misc_intr_enable,
401 .disable = ar5312_misc_intr_disable,
402 .ack = ar5312_misc_intr_ack,
403 .end = ar5312_misc_intr_end,
404 };
405
406 static irqreturn_t ar5312_ahb_proc_handler(int cpl, void *dev_id)
407 {
408 u32 proc1 = sysRegRead(AR531X_PROC1);
409 u32 procAddr = sysRegRead(AR531X_PROCADDR); /* clears error state */
410 u32 dma1 = sysRegRead(AR531X_DMA1);
411 u32 dmaAddr = sysRegRead(AR531X_DMAADDR); /* clears error state */
412
413 printk("AHB interrupt: PROCADDR=0x%8.8x PROC1=0x%8.8x DMAADDR=0x%8.8x DMA1=0x%8.8x\n",
414 procAddr, proc1, dmaAddr, dma1);
415
416 machine_restart("AHB error"); /* Catastrophic failure */
417 return IRQ_HANDLED;
418 }
419
420
421 static struct irqaction ar5312_ahb_proc_interrupt = {
422 .handler = ar5312_ahb_proc_handler,
423 .flags = SA_INTERRUPT,
424 .name = "ar5312_ahb_proc_interrupt",
425 };
426
427
428 static struct irqaction cascade = {
429 .handler = no_action,
430 .flags = SA_INTERRUPT,
431 .name = "cascade",
432 };
433
434 void __init ar5312_misc_intr_init(int irq_base)
435 {
436 int i;
437
438 for (i = irq_base; i < irq_base + AR531X_MISC_IRQ_COUNT; i++) {
439 irq_desc[i].status = IRQ_DISABLED;
440 irq_desc[i].action = NULL;
441 irq_desc[i].depth = 1;
442 irq_desc[i].chip = &ar5312_misc_intr_controller;
443 }
444 setup_irq(AR531X_MISC_IRQ_AHB_PROC, &ar5312_ahb_proc_interrupt);
445 setup_irq(AR5312_IRQ_MISC_INTRS, &cascade);
446 }
447
448
449 void __init ar5312_plat_setup(void)
450 {
451 /* Clear any lingering AHB errors */
452 sysRegRead(AR531X_PROCADDR);
453 sysRegRead(AR531X_DMAADDR);
454 sysRegWrite(AR531X_WD_CTRL, AR531X_WD_CTRL_IGNORE_EXPIRATION);
455
456 board_time_init = ar5312_time_init;
457
458 _machine_restart = ar5312_restart;
459 _machine_halt = ar5312_halt;
460 pm_power_off = ar5312_power_off;
461
462 serial_setup(KSEG1ADDR(AR531X_UART0), ar5312_sys_frequency());
463 }
464
465 arch_initcall(ar5312_init_devices);