b0db7c1d024f724bfd5a10ffea0c1f6a097c42b6
[openwrt/svn-archive/archive.git] / target / linux / atheros-2.6 / files / arch / mips / atheros / ar5315.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/platform_device.h>
22 #include <linux/kernel.h>
23 #include <linux/reboot.h>
24 #include <asm/bootinfo.h>
25 #include <asm/reboot.h>
26 #include <asm/time.h>
27 #include <asm/irq.h>
28 #include <asm/io.h>
29 #include "ar531x.h"
30
31 static struct resource ar5315_eth_res[] = {
32 {
33 .name = "eth_membase",
34 .flags = IORESOURCE_MEM,
35 .start = AR5315_ENET0,
36 .end = AR5315_ENET0 + 0x2000,
37 },
38 {
39 .name = "eth_irq",
40 .flags = IORESOURCE_IRQ,
41 .start = AR5315_IRQ_ENET0_INTRS,
42 .end = AR5315_IRQ_ENET0_INTRS,
43 },
44 };
45
46 static struct ar531x_eth ar5315_eth_data = {
47 .phy = 1,
48 .mac = 0,
49 .reset_base = AR5315_RESET,
50 .reset_mac = AR5315_RESET_ENET0,
51 .reset_phy = AR5315_RESET_EPHY0,
52 };
53
54 static struct platform_device ar5315_eth = {
55 .id = 0,
56 .name = "ar531x-eth",
57 .dev.platform_data = &ar5315_eth_data,
58 .resource = ar5315_eth_res,
59 .num_resources = ARRAY_SIZE(ar5315_eth_res)
60 };
61
62 static struct platform_device ar5315_wmac = {
63 .id = 0,
64 .name = "ar531x-wmac",
65 /* FIXME: add resources */
66 };
67
68 static struct resource ar5315_spiflash_res[] = {
69 {
70 .name = "flash_base",
71 .flags = IORESOURCE_MEM,
72 .start = KSEG1ADDR(AR5315_SPI_READ),
73 .end = KSEG1ADDR(AR5315_SPI_READ) + 0x800000,
74 },
75 {
76 .name = "flash_regs",
77 .flags = IORESOURCE_MEM,
78 .start = 0x11300000,
79 .end = 0x11300012,
80 },
81 };
82
83 static struct platform_device ar5315_spiflash = {
84 .id = 0,
85 .name = "spiflash",
86 .resource = ar5315_spiflash_res,
87 .num_resources = ARRAY_SIZE(ar5315_spiflash_res)
88 };
89
90 static __initdata struct platform_device *ar5315_devs[4];
91
92
93
94 static void *flash_regs;
95
96 static inline __u32 spiflash_regread32(int reg)
97 {
98 volatile __u32 *data = (__u32 *)(flash_regs + reg);
99
100 return (*data);
101 }
102
103 static inline void spiflash_regwrite32(int reg, __u32 data)
104 {
105 volatile __u32 *addr = (__u32 *)(flash_regs + reg);
106
107 *addr = data;
108 }
109
110 #define SPI_FLASH_CTL 0x00
111 #define SPI_FLASH_OPCODE 0x04
112 #define SPI_FLASH_DATA 0x08
113
114 static __u8 spiflash_probe(void)
115 {
116 __u32 reg;
117
118 do {
119 reg = spiflash_regread32(SPI_FLASH_CTL);
120 } while (reg & SPI_CTL_BUSY);
121
122 spiflash_regwrite32(SPI_FLASH_OPCODE, 0xab);
123
124 reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | 4 |
125 (1 << 4) | SPI_CTL_START;
126
127 spiflash_regwrite32(SPI_FLASH_CTL, reg);
128
129 do {
130 reg = spiflash_regread32(SPI_FLASH_CTL);
131 } while (reg & SPI_CTL_BUSY);
132
133 reg = (__u32) spiflash_regread32(SPI_FLASH_DATA);
134 reg &= 0xff;
135
136 return (u8) reg;
137 }
138
139
140 #define STM_8MBIT_SIGNATURE 0x13
141 #define STM_16MBIT_SIGNATURE 0x14
142 #define STM_32MBIT_SIGNATURE 0x15
143 #define STM_64MBIT_SIGNATURE 0x16
144
145
146 static char __init *ar5315_flash_limit(void)
147 {
148 u8 sig;
149 u32 flash_size = 0;
150
151 /* probe the flash chip size */
152 flash_regs = ioremap_nocache(ar5315_spiflash_res[1].start, ar5315_spiflash_res[1].end - ar5315_spiflash_res[1].start);
153 sig = spiflash_probe();
154 iounmap(flash_regs);
155
156 switch(sig) {
157 case STM_8MBIT_SIGNATURE:
158 flash_size = 0x00100000;
159 break;
160 case STM_16MBIT_SIGNATURE:
161 flash_size = 0x00200000;
162 break;
163 case STM_32MBIT_SIGNATURE:
164 flash_size = 0x00400000;
165 break;
166 case STM_64MBIT_SIGNATURE:
167 flash_size = 0x00800000;
168 break;
169 }
170
171 ar5315_spiflash_res[0].end = ar5315_spiflash_res[0].start + flash_size;
172 return (char *) ar5315_spiflash_res[0].end;
173 }
174
175 int __init ar5315_init_devices(void)
176 {
177 struct ar531x_config *config;
178 int dev = 0;
179
180 if (mips_machtype != MACH_ATHEROS_AR5315)
181 return 0;
182
183 ar531x_find_config(ar5315_flash_limit());
184
185 config = (struct ar531x_config *) kzalloc(sizeof(struct ar531x_config), GFP_KERNEL);
186 config->board = board_config;
187 config->radio = radio_config;
188 config->unit = 0;
189 config->tag = (u_int16_t) (sysRegRead(AR5315_SREV) & REV_CHIP);
190
191 ar5315_eth_data.board_config = board_config;
192 ar5315_wmac.dev.platform_data = config;
193
194 ar5315_devs[dev++] = &ar5315_eth;
195 ar5315_devs[dev++] = &ar5315_wmac;
196 ar5315_devs[dev++] = &ar5315_spiflash;
197
198 return platform_add_devices(ar5315_devs, dev);
199 }
200
201
202 /*
203 * Called when an interrupt is received, this function
204 * determines exactly which interrupt it was, and it
205 * invokes the appropriate handler.
206 *
207 * Implicitly, we also define interrupt priority by
208 * choosing which to dispatch first.
209 */
210 asmlinkage void ar5315_irq_dispatch(void)
211 {
212 int pending = read_c0_status() & read_c0_cause();
213
214 if (pending & CAUSEF_IP3)
215 do_IRQ(AR5315_IRQ_WLAN0_INTRS);
216 else if (pending & CAUSEF_IP4)
217 do_IRQ(AR5315_IRQ_ENET0_INTRS);
218 else if (pending & CAUSEF_IP2) {
219 unsigned int ar531x_misc_intrs = sysRegRead(AR5315_ISR) & sysRegRead(AR5315_IMR);
220
221 if (ar531x_misc_intrs & AR5315_ISR_TIMER)
222 do_IRQ(AR531X_MISC_IRQ_TIMER);
223 else if (ar531x_misc_intrs & AR5315_ISR_AHB)
224 do_IRQ(AR531X_MISC_IRQ_AHB_PROC);
225 else if (ar531x_misc_intrs & AR5315_ISR_GPIO) {
226 sysRegWrite(AR5315_ISR, sysRegRead(AR5315_IMR) | ~AR5315_ISR_GPIO);
227 } else if (ar531x_misc_intrs & AR5315_ISR_UART0)
228 do_IRQ(AR531X_MISC_IRQ_UART0);
229 else if (ar531x_misc_intrs & AR5315_ISR_WD)
230 do_IRQ(AR531X_MISC_IRQ_WATCHDOG);
231 else
232 do_IRQ(AR531X_MISC_IRQ_NONE);
233 } else if (pending & CAUSEF_IP7)
234 do_IRQ(AR531X_IRQ_CPU_CLOCK);
235 else
236 do_IRQ(AR531X_IRQ_NONE);
237 }
238
239 static void ar5315_halt(void)
240 {
241 while (1);
242 }
243
244 static void ar5315_power_off(void)
245 {
246 ar5315_halt();
247 }
248
249
250 static void ar5315_restart(char *command)
251 {
252 unsigned int reg;
253 for(;;) {
254
255 /* reset the system */
256 sysRegWrite(AR5315_COLD_RESET,AR5317_RESET_SYSTEM);
257
258 /*
259 * Cold reset does not work on the AR2315/6, use the GPIO reset bits a workaround.
260 */
261
262 reg = sysRegRead(AR5315_GPIO_DO);
263 reg &= ~(1 << AR5315_RESET_GPIO);
264 sysRegWrite(AR5315_GPIO_DO, reg);
265 (void)sysRegRead(AR5315_GPIO_DO); /* flush write to hardware */
266 }
267 }
268
269
270 /*
271 * This table is indexed by bits 5..4 of the CLOCKCTL1 register
272 * to determine the predevisor value.
273 */
274 static int __initdata CLOCKCTL1_PREDIVIDE_TABLE[4] = {
275 1,
276 2,
277 4,
278 5
279 };
280
281 static int __initdata PLLC_DIVIDE_TABLE[5] = {
282 2,
283 3,
284 4,
285 6,
286 3
287 };
288
289 static unsigned int __init
290 ar5315_sys_clk(unsigned int clockCtl)
291 {
292 unsigned int pllcCtrl,cpuDiv;
293 unsigned int pllcOut,refdiv,fdiv,divby2;
294 unsigned int clkDiv;
295
296 pllcCtrl = sysRegRead(AR5315_PLLC_CTL);
297 refdiv = (pllcCtrl & PLLC_REF_DIV_M) >> PLLC_REF_DIV_S;
298 refdiv = CLOCKCTL1_PREDIVIDE_TABLE[refdiv];
299 fdiv = (pllcCtrl & PLLC_FDBACK_DIV_M) >> PLLC_FDBACK_DIV_S;
300 divby2 = (pllcCtrl & PLLC_ADD_FDBACK_DIV_M) >> PLLC_ADD_FDBACK_DIV_S;
301 divby2 += 1;
302 pllcOut = (40000000/refdiv)*(2*divby2)*fdiv;
303
304
305 /* clkm input selected */
306 switch(clockCtl & CPUCLK_CLK_SEL_M) {
307 case 0:
308 case 1:
309 clkDiv = PLLC_DIVIDE_TABLE[(pllcCtrl & PLLC_CLKM_DIV_M) >> PLLC_CLKM_DIV_S];
310 break;
311 case 2:
312 clkDiv = PLLC_DIVIDE_TABLE[(pllcCtrl & PLLC_CLKC_DIV_M) >> PLLC_CLKC_DIV_S];
313 break;
314 default:
315 pllcOut = 40000000;
316 clkDiv = 1;
317 break;
318 }
319 cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S;
320 cpuDiv = cpuDiv * 2 ?: 1;
321 return (pllcOut/(clkDiv * cpuDiv));
322 }
323
324 static inline unsigned int ar5315_cpu_frequency(void)
325 {
326 return ar5315_sys_clk(sysRegRead(AR5315_CPUCLK));
327 }
328
329 static inline unsigned int ar5315_apb_frequency(void)
330 {
331 return ar5315_sys_clk(sysRegRead(AR5315_AMBACLK));
332 }
333
334 static void __init ar5315_time_init(void)
335 {
336 mips_hpt_frequency = ar5315_cpu_frequency() / 2;
337 }
338
339
340
341 /* Enable the specified AR531X_MISC_IRQ interrupt */
342 static void
343 ar5315_misc_intr_enable(unsigned int irq)
344 {
345 unsigned int imr;
346
347 imr = sysRegRead(AR5315_IMR);
348 switch(irq)
349 {
350 case AR531X_MISC_IRQ_TIMER:
351 imr |= AR5315_ISR_TIMER;
352 break;
353
354 case AR531X_MISC_IRQ_AHB_PROC:
355 imr |= AR5315_ISR_AHB;
356 break;
357
358 case AR531X_MISC_IRQ_AHB_DMA:
359 imr |= 0/* ?? */;
360 break;
361
362 case AR531X_MISC_IRQ_GPIO:
363 imr |= AR5315_ISR_GPIO;
364 break;
365
366 case AR531X_MISC_IRQ_UART0:
367 imr |= AR5315_ISR_UART0;
368 break;
369
370
371 case AR531X_MISC_IRQ_WATCHDOG:
372 imr |= AR5315_ISR_WD;
373 break;
374
375 case AR531X_MISC_IRQ_LOCAL:
376 imr |= 0/* ?? */;
377 break;
378
379 }
380 sysRegWrite(AR5315_IMR, imr);
381 imr=sysRegRead(AR5315_IMR); /* flush write buffer */
382 //printk("enable Interrupt irq 0x%x imr 0x%x \n",irq,imr);
383
384 }
385
386 /* Disable the specified AR531X_MISC_IRQ interrupt */
387 static void
388 ar5315_misc_intr_disable(unsigned int irq)
389 {
390 unsigned int imr;
391
392 imr = sysRegRead(AR5315_IMR);
393 switch(irq)
394 {
395 case AR531X_MISC_IRQ_TIMER:
396 imr &= (~AR5315_ISR_TIMER);
397 break;
398
399 case AR531X_MISC_IRQ_AHB_PROC:
400 imr &= (~AR5315_ISR_AHB);
401 break;
402
403 case AR531X_MISC_IRQ_AHB_DMA:
404 imr &= 0/* ?? */;
405 break;
406
407 case AR531X_MISC_IRQ_GPIO:
408 imr &= ~AR5315_ISR_GPIO;
409 break;
410
411 case AR531X_MISC_IRQ_UART0:
412 imr &= (~AR5315_ISR_UART0);
413 break;
414
415 case AR531X_MISC_IRQ_WATCHDOG:
416 imr &= (~AR5315_ISR_WD);
417 break;
418
419 case AR531X_MISC_IRQ_LOCAL:
420 imr &= ~0/* ?? */;
421 break;
422
423 }
424 sysRegWrite(AR5315_IMR, imr);
425 sysRegRead(AR5315_IMR); /* flush write buffer */
426 }
427
428 /* Turn on the specified AR531X_MISC_IRQ interrupt */
429 static unsigned int
430 ar5315_misc_intr_startup(unsigned int irq)
431 {
432 ar5315_misc_intr_enable(irq);
433 return 0;
434 }
435
436 /* Turn off the specified AR531X_MISC_IRQ interrupt */
437 static void
438 ar5315_misc_intr_shutdown(unsigned int irq)
439 {
440 ar5315_misc_intr_disable(irq);
441 }
442
443 static void
444 ar5315_misc_intr_ack(unsigned int irq)
445 {
446 ar5315_misc_intr_disable(irq);
447 }
448
449 static void
450 ar5315_misc_intr_end(unsigned int irq)
451 {
452 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
453 ar5315_misc_intr_enable(irq);
454 }
455
456 static struct irq_chip ar5315_misc_intr_controller = {
457 .typename = "AR5315 misc",
458 .startup = ar5315_misc_intr_startup,
459 .shutdown = ar5315_misc_intr_shutdown,
460 .enable = ar5315_misc_intr_enable,
461 .disable = ar5315_misc_intr_disable,
462 .ack = ar5315_misc_intr_ack,
463 .end = ar5315_misc_intr_end,
464 };
465
466 static irqreturn_t ar5315_ahb_proc_handler(int cpl, void *dev_id)
467 {
468 sysRegWrite(AR5315_AHB_ERR0,AHB_ERROR_DET);
469 sysRegRead(AR5315_AHB_ERR1);
470
471 printk("AHB fatal error\n");
472 machine_restart("AHB error"); /* Catastrophic failure */
473
474 return IRQ_HANDLED;
475 }
476
477 static struct irqaction ar5315_ahb_proc_interrupt = {
478 .handler = ar5315_ahb_proc_handler,
479 .flags = SA_INTERRUPT,
480 .name = "ar5315_ahb_proc_interrupt",
481 };
482
483
484 static struct irqaction cascade = {
485 .handler = no_action,
486 .flags = SA_INTERRUPT,
487 .name = "cascade",
488 };
489
490 void ar5315_misc_intr_init(int irq_base)
491 {
492 int i;
493
494 for (i = irq_base; i < irq_base + AR531X_MISC_IRQ_COUNT; i++) {
495 irq_desc[i].status = IRQ_DISABLED;
496 irq_desc[i].action = NULL;
497 irq_desc[i].depth = 1;
498 irq_desc[i].chip = &ar5315_misc_intr_controller;
499 }
500 setup_irq(AR531X_MISC_IRQ_AHB_PROC, &ar5315_ahb_proc_interrupt);
501 setup_irq(AR5315_IRQ_MISC_INTRS, &cascade);
502 }
503
504 void __init ar5315_plat_setup(void)
505 {
506 unsigned int config = read_c0_config();
507
508 /* Clear any lingering AHB errors */
509 write_c0_config(config & ~0x3);
510 sysRegWrite(AR5315_AHB_ERR0,AHB_ERROR_DET);
511 sysRegRead(AR5315_AHB_ERR1);
512 sysRegWrite(AR5315_WDC, WDC_IGNORE_EXPIRATION);
513
514 board_time_init = ar5315_time_init;
515
516 _machine_restart = ar5315_restart;
517 _machine_halt = ar5315_halt;
518 pm_power_off = ar5315_power_off;
519
520 serial_setup(KSEG1ADDR(AR5315_UART0), ar5315_apb_frequency());
521 }
522
523 arch_initcall(ar5315_init_devices);