ARM: orion: Consolidate the XOR platform setup code.
[pandora-kernel.git] / arch / arm / mach-kirkwood / common.c
1 /*
2  * arch/arm/mach-kirkwood/common.c
3  *
4  * Core functions for Marvell Kirkwood SoCs
5  *
6  * This file is licensed under the terms of the GNU General Public
7  * License version 2.  This program is licensed "as is" without any
8  * warranty of any kind, whether express or implied.
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/platform_device.h>
14 #include <linux/serial_8250.h>
15 #include <linux/mbus.h>
16 #include <linux/ata_platform.h>
17 #include <linux/mtd/nand.h>
18 #include <linux/dma-mapping.h>
19 #include <net/dsa.h>
20 #include <asm/page.h>
21 #include <asm/timex.h>
22 #include <asm/kexec.h>
23 #include <asm/mach/map.h>
24 #include <asm/mach/time.h>
25 #include <mach/kirkwood.h>
26 #include <mach/bridge-regs.h>
27 #include <plat/audio.h>
28 #include <plat/cache-feroceon-l2.h>
29 #include <plat/ehci-orion.h>
30 #include <plat/mvsdio.h>
31 #include <plat/orion_nand.h>
32 #include <plat/common.h>
33 #include <plat/time.h>
34 #include "common.h"
35
36 /*****************************************************************************
37  * I/O Address Mapping
38  ****************************************************************************/
39 static struct map_desc kirkwood_io_desc[] __initdata = {
40         {
41                 .virtual        = KIRKWOOD_PCIE_IO_VIRT_BASE,
42                 .pfn            = __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE),
43                 .length         = KIRKWOOD_PCIE_IO_SIZE,
44                 .type           = MT_DEVICE,
45         }, {
46                 .virtual        = KIRKWOOD_PCIE1_IO_VIRT_BASE,
47                 .pfn            = __phys_to_pfn(KIRKWOOD_PCIE1_IO_PHYS_BASE),
48                 .length         = KIRKWOOD_PCIE1_IO_SIZE,
49                 .type           = MT_DEVICE,
50         }, {
51                 .virtual        = KIRKWOOD_REGS_VIRT_BASE,
52                 .pfn            = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
53                 .length         = KIRKWOOD_REGS_SIZE,
54                 .type           = MT_DEVICE,
55         },
56 };
57
58 void __init kirkwood_map_io(void)
59 {
60         iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc));
61 }
62
63 /*
64  * Default clock control bits.  Any bit _not_ set in this variable
65  * will be cleared from the hardware after platform devices have been
66  * registered.  Some reserved bits must be set to 1.
67  */
68 unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED;
69
70
71 /*****************************************************************************
72  * EHCI
73  ****************************************************************************/
74 static struct orion_ehci_data kirkwood_ehci_data = {
75         .dram           = &kirkwood_mbus_dram_info,
76         .phy_version    = EHCI_PHY_NA,
77 };
78
79 static u64 ehci_dmamask = DMA_BIT_MASK(32);
80
81
82 /*****************************************************************************
83  * EHCI0
84  ****************************************************************************/
85 static struct resource kirkwood_ehci_resources[] = {
86         {
87                 .start  = USB_PHYS_BASE,
88                 .end    = USB_PHYS_BASE + SZ_4K - 1,
89                 .flags  = IORESOURCE_MEM,
90         }, {
91                 .start  = IRQ_KIRKWOOD_USB,
92                 .end    = IRQ_KIRKWOOD_USB,
93                 .flags  = IORESOURCE_IRQ,
94         },
95 };
96
97 static struct platform_device kirkwood_ehci = {
98         .name           = "orion-ehci",
99         .id             = 0,
100         .dev            = {
101                 .dma_mask               = &ehci_dmamask,
102                 .coherent_dma_mask      = DMA_BIT_MASK(32),
103                 .platform_data          = &kirkwood_ehci_data,
104         },
105         .resource       = kirkwood_ehci_resources,
106         .num_resources  = ARRAY_SIZE(kirkwood_ehci_resources),
107 };
108
109 void __init kirkwood_ehci_init(void)
110 {
111         kirkwood_clk_ctrl |= CGC_USB0;
112         platform_device_register(&kirkwood_ehci);
113 }
114
115
116 /*****************************************************************************
117  * GE00
118  ****************************************************************************/
119 void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
120 {
121         kirkwood_clk_ctrl |= CGC_GE0;
122
123         orion_ge00_init(eth_data, &kirkwood_mbus_dram_info,
124                         GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM,
125                         IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk);
126 }
127
128
129 /*****************************************************************************
130  * GE01
131  ****************************************************************************/
132 void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
133 {
134
135         kirkwood_clk_ctrl |= CGC_GE1;
136
137         orion_ge01_init(eth_data, &kirkwood_mbus_dram_info,
138                         GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM,
139                         IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk);
140 }
141
142
143 /*****************************************************************************
144  * Ethernet switch
145  ****************************************************************************/
146 void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq)
147 {
148         orion_ge00_switch_init(d, irq);
149 }
150
151
152 /*****************************************************************************
153  * NAND flash
154  ****************************************************************************/
155 static struct resource kirkwood_nand_resource = {
156         .flags          = IORESOURCE_MEM,
157         .start          = KIRKWOOD_NAND_MEM_PHYS_BASE,
158         .end            = KIRKWOOD_NAND_MEM_PHYS_BASE +
159                                 KIRKWOOD_NAND_MEM_SIZE - 1,
160 };
161
162 static struct orion_nand_data kirkwood_nand_data = {
163         .cle            = 0,
164         .ale            = 1,
165         .width          = 8,
166 };
167
168 static struct platform_device kirkwood_nand_flash = {
169         .name           = "orion_nand",
170         .id             = -1,
171         .dev            = {
172                 .platform_data  = &kirkwood_nand_data,
173         },
174         .resource       = &kirkwood_nand_resource,
175         .num_resources  = 1,
176 };
177
178 void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts,
179                                int chip_delay)
180 {
181         kirkwood_clk_ctrl |= CGC_RUNIT;
182         kirkwood_nand_data.parts = parts;
183         kirkwood_nand_data.nr_parts = nr_parts;
184         kirkwood_nand_data.chip_delay = chip_delay;
185         platform_device_register(&kirkwood_nand_flash);
186 }
187
188 void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts,
189                                    int (*dev_ready)(struct mtd_info *))
190 {
191         kirkwood_clk_ctrl |= CGC_RUNIT;
192         kirkwood_nand_data.parts = parts;
193         kirkwood_nand_data.nr_parts = nr_parts;
194         kirkwood_nand_data.dev_ready = dev_ready;
195         platform_device_register(&kirkwood_nand_flash);
196 }
197
198 /*****************************************************************************
199  * SoC RTC
200  ****************************************************************************/
201 static void __init kirkwood_rtc_init(void)
202 {
203         orion_rtc_init(RTC_PHYS_BASE, IRQ_KIRKWOOD_RTC);
204 }
205
206
207 /*****************************************************************************
208  * SATA
209  ****************************************************************************/
210 static struct resource kirkwood_sata_resources[] = {
211         {
212                 .name   = "sata base",
213                 .start  = SATA_PHYS_BASE,
214                 .end    = SATA_PHYS_BASE + 0x5000 - 1,
215                 .flags  = IORESOURCE_MEM,
216         }, {
217                 .name   = "sata irq",
218                 .start  = IRQ_KIRKWOOD_SATA,
219                 .end    = IRQ_KIRKWOOD_SATA,
220                 .flags  = IORESOURCE_IRQ,
221         },
222 };
223
224 static struct platform_device kirkwood_sata = {
225         .name           = "sata_mv",
226         .id             = 0,
227         .dev            = {
228                 .coherent_dma_mask      = DMA_BIT_MASK(32),
229         },
230         .num_resources  = ARRAY_SIZE(kirkwood_sata_resources),
231         .resource       = kirkwood_sata_resources,
232 };
233
234 void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
235 {
236         kirkwood_clk_ctrl |= CGC_SATA0;
237         if (sata_data->n_ports > 1)
238                 kirkwood_clk_ctrl |= CGC_SATA1;
239         sata_data->dram = &kirkwood_mbus_dram_info;
240         kirkwood_sata.dev.platform_data = sata_data;
241         platform_device_register(&kirkwood_sata);
242 }
243
244
245 /*****************************************************************************
246  * SD/SDIO/MMC
247  ****************************************************************************/
248 static struct resource mvsdio_resources[] = {
249         [0] = {
250                 .start  = SDIO_PHYS_BASE,
251                 .end    = SDIO_PHYS_BASE + SZ_1K - 1,
252                 .flags  = IORESOURCE_MEM,
253         },
254         [1] = {
255                 .start  = IRQ_KIRKWOOD_SDIO,
256                 .end    = IRQ_KIRKWOOD_SDIO,
257                 .flags  = IORESOURCE_IRQ,
258         },
259 };
260
261 static u64 mvsdio_dmamask = DMA_BIT_MASK(32);
262
263 static struct platform_device kirkwood_sdio = {
264         .name           = "mvsdio",
265         .id             = -1,
266         .dev            = {
267                 .dma_mask = &mvsdio_dmamask,
268                 .coherent_dma_mask = DMA_BIT_MASK(32),
269         },
270         .num_resources  = ARRAY_SIZE(mvsdio_resources),
271         .resource       = mvsdio_resources,
272 };
273
274 void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
275 {
276         u32 dev, rev;
277
278         kirkwood_pcie_id(&dev, &rev);
279         if (rev == 0 && dev != MV88F6282_DEV_ID) /* catch all Kirkwood Z0's */
280                 mvsdio_data->clock = 100000000;
281         else
282                 mvsdio_data->clock = 200000000;
283         mvsdio_data->dram = &kirkwood_mbus_dram_info;
284         kirkwood_clk_ctrl |= CGC_SDIO;
285         kirkwood_sdio.dev.platform_data = mvsdio_data;
286         platform_device_register(&kirkwood_sdio);
287 }
288
289
290 /*****************************************************************************
291  * SPI
292  ****************************************************************************/
293 void __init kirkwood_spi_init()
294 {
295         kirkwood_clk_ctrl |= CGC_RUNIT;
296         orion_spi_init(SPI_PHYS_BASE, kirkwood_tclk);
297 }
298
299
300 /*****************************************************************************
301  * I2C
302  ****************************************************************************/
303 void __init kirkwood_i2c_init(void)
304 {
305         orion_i2c_init(I2C_PHYS_BASE, IRQ_KIRKWOOD_TWSI, 8);
306 }
307
308
309 /*****************************************************************************
310  * UART0
311  ****************************************************************************/
312
313 void __init kirkwood_uart0_init(void)
314 {
315         orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
316                          IRQ_KIRKWOOD_UART_0, kirkwood_tclk);
317 }
318
319
320 /*****************************************************************************
321  * UART1
322  ****************************************************************************/
323 void __init kirkwood_uart1_init(void)
324 {
325         orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
326                          IRQ_KIRKWOOD_UART_1, kirkwood_tclk);
327 }
328
329 /*****************************************************************************
330  * Cryptographic Engines and Security Accelerator (CESA)
331  ****************************************************************************/
332
333 static struct resource kirkwood_crypto_res[] = {
334         {
335                 .name   = "regs",
336                 .start  = CRYPTO_PHYS_BASE,
337                 .end    = CRYPTO_PHYS_BASE + 0xffff,
338                 .flags  = IORESOURCE_MEM,
339         }, {
340                 .name   = "sram",
341                 .start  = KIRKWOOD_SRAM_PHYS_BASE,
342                 .end    = KIRKWOOD_SRAM_PHYS_BASE + KIRKWOOD_SRAM_SIZE - 1,
343                 .flags  = IORESOURCE_MEM,
344         }, {
345                 .name   = "crypto interrupt",
346                 .start  = IRQ_KIRKWOOD_CRYPTO,
347                 .end    = IRQ_KIRKWOOD_CRYPTO,
348                 .flags  = IORESOURCE_IRQ,
349         },
350 };
351
352 static struct platform_device kirkwood_crypto_device = {
353         .name           = "mv_crypto",
354         .id             = -1,
355         .num_resources  = ARRAY_SIZE(kirkwood_crypto_res),
356         .resource       = kirkwood_crypto_res,
357 };
358
359 void __init kirkwood_crypto_init(void)
360 {
361         kirkwood_clk_ctrl |= CGC_CRYPTO;
362         platform_device_register(&kirkwood_crypto_device);
363 }
364
365
366 /*****************************************************************************
367  * XOR0
368  ****************************************************************************/
369 static void __init kirkwood_xor0_init(void)
370 {
371         kirkwood_clk_ctrl |= CGC_XOR0;
372
373         orion_xor0_init(&kirkwood_mbus_dram_info,
374                         XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE,
375                         IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01);
376 }
377
378
379 /*****************************************************************************
380  * XOR1
381  ****************************************************************************/
382 static void __init kirkwood_xor1_init(void)
383 {
384         kirkwood_clk_ctrl |= CGC_XOR1;
385
386         orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE,
387                         IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11);
388 }
389
390
391 /*****************************************************************************
392  * Watchdog
393  ****************************************************************************/
394 static void __init kirkwood_wdt_init(void)
395 {
396         orion_wdt_init(kirkwood_tclk);
397 }
398
399
400 /*****************************************************************************
401  * Time handling
402  ****************************************************************************/
403 void __init kirkwood_init_early(void)
404 {
405         orion_time_set_base(TIMER_VIRT_BASE);
406 }
407
408 int kirkwood_tclk;
409
410 static int __init kirkwood_find_tclk(void)
411 {
412         u32 dev, rev;
413
414         kirkwood_pcie_id(&dev, &rev);
415
416         if (dev == MV88F6281_DEV_ID || dev == MV88F6282_DEV_ID)
417                 if (((readl(SAMPLE_AT_RESET) >> 21) & 1) == 0)
418                         return 200000000;
419
420         return 166666667;
421 }
422
423 static void __init kirkwood_timer_init(void)
424 {
425         kirkwood_tclk = kirkwood_find_tclk();
426
427         orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
428                         IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
429 }
430
431 struct sys_timer kirkwood_timer = {
432         .init = kirkwood_timer_init,
433 };
434
435 /*****************************************************************************
436  * Audio
437  ****************************************************************************/
438 static struct resource kirkwood_i2s_resources[] = {
439         [0] = {
440                 .start  = AUDIO_PHYS_BASE,
441                 .end    = AUDIO_PHYS_BASE + SZ_16K - 1,
442                 .flags  = IORESOURCE_MEM,
443         },
444         [1] = {
445                 .start  = IRQ_KIRKWOOD_I2S,
446                 .end    = IRQ_KIRKWOOD_I2S,
447                 .flags  = IORESOURCE_IRQ,
448         },
449 };
450
451 static struct kirkwood_asoc_platform_data kirkwood_i2s_data = {
452         .dram        = &kirkwood_mbus_dram_info,
453         .burst       = 128,
454 };
455
456 static struct platform_device kirkwood_i2s_device = {
457         .name           = "kirkwood-i2s",
458         .id             = -1,
459         .num_resources  = ARRAY_SIZE(kirkwood_i2s_resources),
460         .resource       = kirkwood_i2s_resources,
461         .dev            = {
462                 .platform_data  = &kirkwood_i2s_data,
463         },
464 };
465
466 static struct platform_device kirkwood_pcm_device = {
467         .name           = "kirkwood-pcm-audio",
468         .id             = -1,
469 };
470
471 void __init kirkwood_audio_init(void)
472 {
473         kirkwood_clk_ctrl |= CGC_AUDIO;
474         platform_device_register(&kirkwood_i2s_device);
475         platform_device_register(&kirkwood_pcm_device);
476 }
477
478 /*****************************************************************************
479  * General
480  ****************************************************************************/
481 /*
482  * Identify device ID and revision.
483  */
484 static char * __init kirkwood_id(void)
485 {
486         u32 dev, rev;
487
488         kirkwood_pcie_id(&dev, &rev);
489
490         if (dev == MV88F6281_DEV_ID) {
491                 if (rev == MV88F6281_REV_Z0)
492                         return "MV88F6281-Z0";
493                 else if (rev == MV88F6281_REV_A0)
494                         return "MV88F6281-A0";
495                 else if (rev == MV88F6281_REV_A1)
496                         return "MV88F6281-A1";
497                 else
498                         return "MV88F6281-Rev-Unsupported";
499         } else if (dev == MV88F6192_DEV_ID) {
500                 if (rev == MV88F6192_REV_Z0)
501                         return "MV88F6192-Z0";
502                 else if (rev == MV88F6192_REV_A0)
503                         return "MV88F6192-A0";
504                 else if (rev == MV88F6192_REV_A1)
505                         return "MV88F6192-A1";
506                 else
507                         return "MV88F6192-Rev-Unsupported";
508         } else if (dev == MV88F6180_DEV_ID) {
509                 if (rev == MV88F6180_REV_A0)
510                         return "MV88F6180-Rev-A0";
511                 else if (rev == MV88F6180_REV_A1)
512                         return "MV88F6180-Rev-A1";
513                 else
514                         return "MV88F6180-Rev-Unsupported";
515         } else if (dev == MV88F6282_DEV_ID) {
516                 if (rev == MV88F6282_REV_A0)
517                         return "MV88F6282-Rev-A0";
518                 else
519                         return "MV88F6282-Rev-Unsupported";
520         } else {
521                 return "Device-Unknown";
522         }
523 }
524
525 static void __init kirkwood_l2_init(void)
526 {
527 #ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH
528         writel(readl(L2_CONFIG_REG) | L2_WRITETHROUGH, L2_CONFIG_REG);
529         feroceon_l2_init(1);
530 #else
531         writel(readl(L2_CONFIG_REG) & ~L2_WRITETHROUGH, L2_CONFIG_REG);
532         feroceon_l2_init(0);
533 #endif
534 }
535
536 void __init kirkwood_init(void)
537 {
538         printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
539                 kirkwood_id(), kirkwood_tclk);
540         kirkwood_i2s_data.tclk = kirkwood_tclk;
541
542         /*
543          * Disable propagation of mbus errors to the CPU local bus,
544          * as this causes mbus errors (which can occur for example
545          * for PCI aborts) to throw CPU aborts, which we're not set
546          * up to deal with.
547          */
548         writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
549
550         kirkwood_setup_cpu_mbus();
551
552 #ifdef CONFIG_CACHE_FEROCEON_L2
553         kirkwood_l2_init();
554 #endif
555
556         /* internal devices that every board has */
557         kirkwood_rtc_init();
558         kirkwood_wdt_init();
559         kirkwood_xor0_init();
560         kirkwood_xor1_init();
561         kirkwood_crypto_init();
562
563 #ifdef CONFIG_KEXEC 
564         kexec_reinit = kirkwood_enable_pcie;
565 #endif
566 }
567
568 static int __init kirkwood_clock_gate(void)
569 {
570         unsigned int curr = readl(CLOCK_GATING_CTRL);
571         u32 dev, rev;
572
573         kirkwood_pcie_id(&dev, &rev);
574         printk(KERN_DEBUG "Gating clock of unused units\n");
575         printk(KERN_DEBUG "before: 0x%08x\n", curr);
576
577         /* Make sure those units are accessible */
578         writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL);
579
580         /* For SATA: first shutdown the phy */
581         if (!(kirkwood_clk_ctrl & CGC_SATA0)) {
582                 /* Disable PLL and IVREF */
583                 writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2);
584                 /* Disable PHY */
585                 writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
586         }
587         if (!(kirkwood_clk_ctrl & CGC_SATA1)) {
588                 /* Disable PLL and IVREF */
589                 writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2);
590                 /* Disable PHY */
591                 writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL);
592         }
593         
594         /* For PCIe: first shutdown the phy */
595         if (!(kirkwood_clk_ctrl & CGC_PEX0)) {
596                 writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL);
597                 while (1)
598                         if (readl(PCIE_STATUS) & 0x1)
599                                 break;
600                 writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
601         }
602
603         /* For PCIe 1: first shutdown the phy */
604         if (dev == MV88F6282_DEV_ID) {
605                 if (!(kirkwood_clk_ctrl & CGC_PEX1)) {
606                         writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL);
607                         while (1)
608                                 if (readl(PCIE1_STATUS) & 0x1)
609                                         break;
610                         writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL);
611                 }
612         } else  /* keep this bit set for devices that don't have PCIe1 */
613                 kirkwood_clk_ctrl |= CGC_PEX1;
614
615         /* Now gate clock the required units */
616         writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
617         printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL));
618
619         return 0;
620 }
621 late_initcall(kirkwood_clock_gate);