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