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