Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec...
[sfrench/cifs-2.6.git] / arch / arm / mach-mv78xx0 / common.c
1 /*
2  * arch/arm/mach-mv78xx0/common.c
3  *
4  * Core functions for Marvell MV78xx0 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/mv643xx_eth.h>
17 #include <linux/mv643xx_i2c.h>
18 #include <linux/ata_platform.h>
19 #include <linux/ethtool.h>
20 #include <asm/mach/map.h>
21 #include <asm/mach/time.h>
22 #include <mach/mv78xx0.h>
23 #include <mach/bridge-regs.h>
24 #include <plat/cache-feroceon-l2.h>
25 #include <plat/ehci-orion.h>
26 #include <plat/orion_nand.h>
27 #include <plat/time.h>
28 #include "common.h"
29
30
31 /*****************************************************************************
32  * Common bits
33  ****************************************************************************/
34 int mv78xx0_core_index(void)
35 {
36         u32 extra;
37
38         /*
39          * Read Extra Features register.
40          */
41         __asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (extra));
42
43         return !!(extra & 0x00004000);
44 }
45
46 static int get_hclk(void)
47 {
48         int hclk;
49
50         /*
51          * HCLK tick rate is configured by DEV_D[7:5] pins.
52          */
53         switch ((readl(SAMPLE_AT_RESET_LOW) >> 5) & 7) {
54         case 0:
55                 hclk = 166666667;
56                 break;
57         case 1:
58                 hclk = 200000000;
59                 break;
60         case 2:
61                 hclk = 266666667;
62                 break;
63         case 3:
64                 hclk = 333333333;
65                 break;
66         case 4:
67                 hclk = 400000000;
68                 break;
69         default:
70                 panic("unknown HCLK PLL setting: %.8x\n",
71                         readl(SAMPLE_AT_RESET_LOW));
72         }
73
74         return hclk;
75 }
76
77 static void get_pclk_l2clk(int hclk, int core_index, int *pclk, int *l2clk)
78 {
79         u32 cfg;
80
81         /*
82          * Core #0 PCLK/L2CLK is configured by bits [13:8], core #1
83          * PCLK/L2CLK by bits [19:14].
84          */
85         if (core_index == 0) {
86                 cfg = (readl(SAMPLE_AT_RESET_LOW) >> 8) & 0x3f;
87         } else {
88                 cfg = (readl(SAMPLE_AT_RESET_LOW) >> 14) & 0x3f;
89         }
90
91         /*
92          * Bits [11:8] ([17:14] for core #1) configure the PCLK:HCLK
93          * ratio (1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6).
94          */
95         *pclk = ((u64)hclk * (2 + (cfg & 0xf))) >> 1;
96
97         /*
98          * Bits [13:12] ([19:18] for core #1) configure the PCLK:L2CLK
99          * ratio (1, 2, 3).
100          */
101         *l2clk = *pclk / (((cfg >> 4) & 3) + 1);
102 }
103
104 static int get_tclk(void)
105 {
106         int tclk;
107
108         /*
109          * TCLK tick rate is configured by DEV_A[2:0] strap pins.
110          */
111         switch ((readl(SAMPLE_AT_RESET_HIGH) >> 6) & 7) {
112         case 1:
113                 tclk = 166666667;
114                 break;
115         case 3:
116                 tclk = 200000000;
117                 break;
118         default:
119                 panic("unknown TCLK PLL setting: %.8x\n",
120                         readl(SAMPLE_AT_RESET_HIGH));
121         }
122
123         return tclk;
124 }
125
126
127 /*****************************************************************************
128  * I/O Address Mapping
129  ****************************************************************************/
130 static struct map_desc mv78xx0_io_desc[] __initdata = {
131         {
132                 .virtual        = MV78XX0_CORE_REGS_VIRT_BASE,
133                 .pfn            = 0,
134                 .length         = MV78XX0_CORE_REGS_SIZE,
135                 .type           = MT_DEVICE,
136         }, {
137                 .virtual        = MV78XX0_PCIE_IO_VIRT_BASE(0),
138                 .pfn            = __phys_to_pfn(MV78XX0_PCIE_IO_PHYS_BASE(0)),
139                 .length         = MV78XX0_PCIE_IO_SIZE * 8,
140                 .type           = MT_DEVICE,
141         }, {
142                 .virtual        = MV78XX0_REGS_VIRT_BASE,
143                 .pfn            = __phys_to_pfn(MV78XX0_REGS_PHYS_BASE),
144                 .length         = MV78XX0_REGS_SIZE,
145                 .type           = MT_DEVICE,
146         },
147 };
148
149 void __init mv78xx0_map_io(void)
150 {
151         unsigned long phys;
152
153         /*
154          * Map the right set of per-core registers depending on
155          * which core we are running on.
156          */
157         if (mv78xx0_core_index() == 0) {
158                 phys = MV78XX0_CORE0_REGS_PHYS_BASE;
159         } else {
160                 phys = MV78XX0_CORE1_REGS_PHYS_BASE;
161         }
162         mv78xx0_io_desc[0].pfn = __phys_to_pfn(phys);
163
164         iotable_init(mv78xx0_io_desc, ARRAY_SIZE(mv78xx0_io_desc));
165 }
166
167
168 /*****************************************************************************
169  * EHCI
170  ****************************************************************************/
171 static struct orion_ehci_data mv78xx0_ehci_data = {
172         .dram           = &mv78xx0_mbus_dram_info,
173         .phy_version    = EHCI_PHY_NA,
174 };
175
176 static u64 ehci_dmamask = 0xffffffffUL;
177
178
179 /*****************************************************************************
180  * EHCI0
181  ****************************************************************************/
182 static struct resource mv78xx0_ehci0_resources[] = {
183         {
184                 .start  = USB0_PHYS_BASE,
185                 .end    = USB0_PHYS_BASE + 0x0fff,
186                 .flags  = IORESOURCE_MEM,
187         }, {
188                 .start  = IRQ_MV78XX0_USB_0,
189                 .end    = IRQ_MV78XX0_USB_0,
190                 .flags  = IORESOURCE_IRQ,
191         },
192 };
193
194 static struct platform_device mv78xx0_ehci0 = {
195         .name           = "orion-ehci",
196         .id             = 0,
197         .dev            = {
198                 .dma_mask               = &ehci_dmamask,
199                 .coherent_dma_mask      = 0xffffffff,
200                 .platform_data          = &mv78xx0_ehci_data,
201         },
202         .resource       = mv78xx0_ehci0_resources,
203         .num_resources  = ARRAY_SIZE(mv78xx0_ehci0_resources),
204 };
205
206 void __init mv78xx0_ehci0_init(void)
207 {
208         platform_device_register(&mv78xx0_ehci0);
209 }
210
211
212 /*****************************************************************************
213  * EHCI1
214  ****************************************************************************/
215 static struct resource mv78xx0_ehci1_resources[] = {
216         {
217                 .start  = USB1_PHYS_BASE,
218                 .end    = USB1_PHYS_BASE + 0x0fff,
219                 .flags  = IORESOURCE_MEM,
220         }, {
221                 .start  = IRQ_MV78XX0_USB_1,
222                 .end    = IRQ_MV78XX0_USB_1,
223                 .flags  = IORESOURCE_IRQ,
224         },
225 };
226
227 static struct platform_device mv78xx0_ehci1 = {
228         .name           = "orion-ehci",
229         .id             = 1,
230         .dev            = {
231                 .dma_mask               = &ehci_dmamask,
232                 .coherent_dma_mask      = 0xffffffff,
233                 .platform_data          = &mv78xx0_ehci_data,
234         },
235         .resource       = mv78xx0_ehci1_resources,
236         .num_resources  = ARRAY_SIZE(mv78xx0_ehci1_resources),
237 };
238
239 void __init mv78xx0_ehci1_init(void)
240 {
241         platform_device_register(&mv78xx0_ehci1);
242 }
243
244
245 /*****************************************************************************
246  * EHCI2
247  ****************************************************************************/
248 static struct resource mv78xx0_ehci2_resources[] = {
249         {
250                 .start  = USB2_PHYS_BASE,
251                 .end    = USB2_PHYS_BASE + 0x0fff,
252                 .flags  = IORESOURCE_MEM,
253         }, {
254                 .start  = IRQ_MV78XX0_USB_2,
255                 .end    = IRQ_MV78XX0_USB_2,
256                 .flags  = IORESOURCE_IRQ,
257         },
258 };
259
260 static struct platform_device mv78xx0_ehci2 = {
261         .name           = "orion-ehci",
262         .id             = 2,
263         .dev            = {
264                 .dma_mask               = &ehci_dmamask,
265                 .coherent_dma_mask      = 0xffffffff,
266                 .platform_data          = &mv78xx0_ehci_data,
267         },
268         .resource       = mv78xx0_ehci2_resources,
269         .num_resources  = ARRAY_SIZE(mv78xx0_ehci2_resources),
270 };
271
272 void __init mv78xx0_ehci2_init(void)
273 {
274         platform_device_register(&mv78xx0_ehci2);
275 }
276
277
278 /*****************************************************************************
279  * GE00
280  ****************************************************************************/
281 struct mv643xx_eth_shared_platform_data mv78xx0_ge00_shared_data = {
282         .t_clk          = 0,
283         .dram           = &mv78xx0_mbus_dram_info,
284 };
285
286 static struct resource mv78xx0_ge00_shared_resources[] = {
287         {
288                 .name   = "ge00 base",
289                 .start  = GE00_PHYS_BASE + 0x2000,
290                 .end    = GE00_PHYS_BASE + 0x3fff,
291                 .flags  = IORESOURCE_MEM,
292         }, {
293                 .name   = "ge err irq",
294                 .start  = IRQ_MV78XX0_GE_ERR,
295                 .end    = IRQ_MV78XX0_GE_ERR,
296                 .flags  = IORESOURCE_IRQ,
297         },
298 };
299
300 static struct platform_device mv78xx0_ge00_shared = {
301         .name           = MV643XX_ETH_SHARED_NAME,
302         .id             = 0,
303         .dev            = {
304                 .platform_data  = &mv78xx0_ge00_shared_data,
305         },
306         .num_resources  = ARRAY_SIZE(mv78xx0_ge00_shared_resources),
307         .resource       = mv78xx0_ge00_shared_resources,
308 };
309
310 static struct resource mv78xx0_ge00_resources[] = {
311         {
312                 .name   = "ge00 irq",
313                 .start  = IRQ_MV78XX0_GE00_SUM,
314                 .end    = IRQ_MV78XX0_GE00_SUM,
315                 .flags  = IORESOURCE_IRQ,
316         },
317 };
318
319 static struct platform_device mv78xx0_ge00 = {
320         .name           = MV643XX_ETH_NAME,
321         .id             = 0,
322         .num_resources  = 1,
323         .resource       = mv78xx0_ge00_resources,
324         .dev            = {
325                 .coherent_dma_mask      = 0xffffffff,
326         },
327 };
328
329 void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
330 {
331         eth_data->shared = &mv78xx0_ge00_shared;
332         mv78xx0_ge00.dev.platform_data = eth_data;
333
334         platform_device_register(&mv78xx0_ge00_shared);
335         platform_device_register(&mv78xx0_ge00);
336 }
337
338
339 /*****************************************************************************
340  * GE01
341  ****************************************************************************/
342 struct mv643xx_eth_shared_platform_data mv78xx0_ge01_shared_data = {
343         .t_clk          = 0,
344         .dram           = &mv78xx0_mbus_dram_info,
345         .shared_smi     = &mv78xx0_ge00_shared,
346 };
347
348 static struct resource mv78xx0_ge01_shared_resources[] = {
349         {
350                 .name   = "ge01 base",
351                 .start  = GE01_PHYS_BASE + 0x2000,
352                 .end    = GE01_PHYS_BASE + 0x3fff,
353                 .flags  = IORESOURCE_MEM,
354         },
355 };
356
357 static struct platform_device mv78xx0_ge01_shared = {
358         .name           = MV643XX_ETH_SHARED_NAME,
359         .id             = 1,
360         .dev            = {
361                 .platform_data  = &mv78xx0_ge01_shared_data,
362         },
363         .num_resources  = 1,
364         .resource       = mv78xx0_ge01_shared_resources,
365 };
366
367 static struct resource mv78xx0_ge01_resources[] = {
368         {
369                 .name   = "ge01 irq",
370                 .start  = IRQ_MV78XX0_GE01_SUM,
371                 .end    = IRQ_MV78XX0_GE01_SUM,
372                 .flags  = IORESOURCE_IRQ,
373         },
374 };
375
376 static struct platform_device mv78xx0_ge01 = {
377         .name           = MV643XX_ETH_NAME,
378         .id             = 1,
379         .num_resources  = 1,
380         .resource       = mv78xx0_ge01_resources,
381         .dev            = {
382                 .coherent_dma_mask      = 0xffffffff,
383         },
384 };
385
386 void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
387 {
388         eth_data->shared = &mv78xx0_ge01_shared;
389         mv78xx0_ge01.dev.platform_data = eth_data;
390
391         platform_device_register(&mv78xx0_ge01_shared);
392         platform_device_register(&mv78xx0_ge01);
393 }
394
395
396 /*****************************************************************************
397  * GE10
398  ****************************************************************************/
399 struct mv643xx_eth_shared_platform_data mv78xx0_ge10_shared_data = {
400         .t_clk          = 0,
401         .dram           = &mv78xx0_mbus_dram_info,
402         .shared_smi     = &mv78xx0_ge00_shared,
403 };
404
405 static struct resource mv78xx0_ge10_shared_resources[] = {
406         {
407                 .name   = "ge10 base",
408                 .start  = GE10_PHYS_BASE + 0x2000,
409                 .end    = GE10_PHYS_BASE + 0x3fff,
410                 .flags  = IORESOURCE_MEM,
411         },
412 };
413
414 static struct platform_device mv78xx0_ge10_shared = {
415         .name           = MV643XX_ETH_SHARED_NAME,
416         .id             = 2,
417         .dev            = {
418                 .platform_data  = &mv78xx0_ge10_shared_data,
419         },
420         .num_resources  = 1,
421         .resource       = mv78xx0_ge10_shared_resources,
422 };
423
424 static struct resource mv78xx0_ge10_resources[] = {
425         {
426                 .name   = "ge10 irq",
427                 .start  = IRQ_MV78XX0_GE10_SUM,
428                 .end    = IRQ_MV78XX0_GE10_SUM,
429                 .flags  = IORESOURCE_IRQ,
430         },
431 };
432
433 static struct platform_device mv78xx0_ge10 = {
434         .name           = MV643XX_ETH_NAME,
435         .id             = 2,
436         .num_resources  = 1,
437         .resource       = mv78xx0_ge10_resources,
438         .dev            = {
439                 .coherent_dma_mask      = 0xffffffff,
440         },
441 };
442
443 void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
444 {
445         u32 dev, rev;
446
447         eth_data->shared = &mv78xx0_ge10_shared;
448         mv78xx0_ge10.dev.platform_data = eth_data;
449
450         /*
451          * On the Z0, ge10 and ge11 are internally connected back
452          * to back, and not brought out.
453          */
454         mv78xx0_pcie_id(&dev, &rev);
455         if (dev == MV78X00_Z0_DEV_ID) {
456                 eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
457                 eth_data->speed = SPEED_1000;
458                 eth_data->duplex = DUPLEX_FULL;
459         }
460
461         platform_device_register(&mv78xx0_ge10_shared);
462         platform_device_register(&mv78xx0_ge10);
463 }
464
465
466 /*****************************************************************************
467  * GE11
468  ****************************************************************************/
469 struct mv643xx_eth_shared_platform_data mv78xx0_ge11_shared_data = {
470         .t_clk          = 0,
471         .dram           = &mv78xx0_mbus_dram_info,
472         .shared_smi     = &mv78xx0_ge00_shared,
473 };
474
475 static struct resource mv78xx0_ge11_shared_resources[] = {
476         {
477                 .name   = "ge11 base",
478                 .start  = GE11_PHYS_BASE + 0x2000,
479                 .end    = GE11_PHYS_BASE + 0x3fff,
480                 .flags  = IORESOURCE_MEM,
481         },
482 };
483
484 static struct platform_device mv78xx0_ge11_shared = {
485         .name           = MV643XX_ETH_SHARED_NAME,
486         .id             = 3,
487         .dev            = {
488                 .platform_data  = &mv78xx0_ge11_shared_data,
489         },
490         .num_resources  = 1,
491         .resource       = mv78xx0_ge11_shared_resources,
492 };
493
494 static struct resource mv78xx0_ge11_resources[] = {
495         {
496                 .name   = "ge11 irq",
497                 .start  = IRQ_MV78XX0_GE11_SUM,
498                 .end    = IRQ_MV78XX0_GE11_SUM,
499                 .flags  = IORESOURCE_IRQ,
500         },
501 };
502
503 static struct platform_device mv78xx0_ge11 = {
504         .name           = MV643XX_ETH_NAME,
505         .id             = 3,
506         .num_resources  = 1,
507         .resource       = mv78xx0_ge11_resources,
508         .dev            = {
509                 .coherent_dma_mask      = 0xffffffff,
510         },
511 };
512
513 void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
514 {
515         u32 dev, rev;
516
517         eth_data->shared = &mv78xx0_ge11_shared;
518         mv78xx0_ge11.dev.platform_data = eth_data;
519
520         /*
521          * On the Z0, ge10 and ge11 are internally connected back
522          * to back, and not brought out.
523          */
524         mv78xx0_pcie_id(&dev, &rev);
525         if (dev == MV78X00_Z0_DEV_ID) {
526                 eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
527                 eth_data->speed = SPEED_1000;
528                 eth_data->duplex = DUPLEX_FULL;
529         }
530
531         platform_device_register(&mv78xx0_ge11_shared);
532         platform_device_register(&mv78xx0_ge11);
533 }
534
535 /*****************************************************************************
536  * I2C bus 0
537  ****************************************************************************/
538
539 static struct mv64xxx_i2c_pdata mv78xx0_i2c_0_pdata = {
540         .freq_m         = 8, /* assumes 166 MHz TCLK */
541         .freq_n         = 3,
542         .timeout        = 1000, /* Default timeout of 1 second */
543 };
544
545 static struct resource mv78xx0_i2c_0_resources[] = {
546         {
547                 .start  = I2C_0_PHYS_BASE,
548                 .end    = I2C_0_PHYS_BASE + 0x1f,
549                 .flags  = IORESOURCE_MEM,
550         }, {
551                 .start  = IRQ_MV78XX0_I2C_0,
552                 .end    = IRQ_MV78XX0_I2C_0,
553                 .flags  = IORESOURCE_IRQ,
554         },
555 };
556
557
558 static struct platform_device mv78xx0_i2c_0 = {
559         .name           = MV64XXX_I2C_CTLR_NAME,
560         .id             = 0,
561         .num_resources  = ARRAY_SIZE(mv78xx0_i2c_0_resources),
562         .resource       = mv78xx0_i2c_0_resources,
563         .dev            = {
564                 .platform_data  = &mv78xx0_i2c_0_pdata,
565         },
566 };
567
568 /*****************************************************************************
569  * I2C bus 1
570  ****************************************************************************/
571
572 static struct mv64xxx_i2c_pdata mv78xx0_i2c_1_pdata = {
573         .freq_m         = 8, /* assumes 166 MHz TCLK */
574         .freq_n         = 3,
575         .timeout        = 1000, /* Default timeout of 1 second */
576 };
577
578 static struct resource mv78xx0_i2c_1_resources[] = {
579         {
580                 .start  = I2C_1_PHYS_BASE,
581                 .end    = I2C_1_PHYS_BASE + 0x1f,
582                 .flags  = IORESOURCE_MEM,
583         }, {
584                 .start  = IRQ_MV78XX0_I2C_1,
585                 .end    = IRQ_MV78XX0_I2C_1,
586                 .flags  = IORESOURCE_IRQ,
587         },
588 };
589
590
591 static struct platform_device mv78xx0_i2c_1 = {
592         .name           = MV64XXX_I2C_CTLR_NAME,
593         .id             = 1,
594         .num_resources  = ARRAY_SIZE(mv78xx0_i2c_1_resources),
595         .resource       = mv78xx0_i2c_1_resources,
596         .dev            = {
597                 .platform_data  = &mv78xx0_i2c_1_pdata,
598         },
599 };
600
601 void __init mv78xx0_i2c_init(void)
602 {
603         platform_device_register(&mv78xx0_i2c_0);
604         platform_device_register(&mv78xx0_i2c_1);
605 }
606
607 /*****************************************************************************
608  * SATA
609  ****************************************************************************/
610 static struct resource mv78xx0_sata_resources[] = {
611         {
612                 .name   = "sata base",
613                 .start  = SATA_PHYS_BASE,
614                 .end    = SATA_PHYS_BASE + 0x5000 - 1,
615                 .flags  = IORESOURCE_MEM,
616         }, {
617                 .name   = "sata irq",
618                 .start  = IRQ_MV78XX0_SATA,
619                 .end    = IRQ_MV78XX0_SATA,
620                 .flags  = IORESOURCE_IRQ,
621         },
622 };
623
624 static struct platform_device mv78xx0_sata = {
625         .name           = "sata_mv",
626         .id             = 0,
627         .dev            = {
628                 .coherent_dma_mask      = 0xffffffff,
629         },
630         .num_resources  = ARRAY_SIZE(mv78xx0_sata_resources),
631         .resource       = mv78xx0_sata_resources,
632 };
633
634 void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data)
635 {
636         sata_data->dram = &mv78xx0_mbus_dram_info;
637         mv78xx0_sata.dev.platform_data = sata_data;
638         platform_device_register(&mv78xx0_sata);
639 }
640
641
642 /*****************************************************************************
643  * UART0
644  ****************************************************************************/
645 static struct plat_serial8250_port mv78xx0_uart0_data[] = {
646         {
647                 .mapbase        = UART0_PHYS_BASE,
648                 .membase        = (char *)UART0_VIRT_BASE,
649                 .irq            = IRQ_MV78XX0_UART_0,
650                 .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
651                 .iotype         = UPIO_MEM,
652                 .regshift       = 2,
653                 .uartclk        = 0,
654         }, {
655         },
656 };
657
658 static struct resource mv78xx0_uart0_resources[] = {
659         {
660                 .start          = UART0_PHYS_BASE,
661                 .end            = UART0_PHYS_BASE + 0xff,
662                 .flags          = IORESOURCE_MEM,
663         }, {
664                 .start          = IRQ_MV78XX0_UART_0,
665                 .end            = IRQ_MV78XX0_UART_0,
666                 .flags          = IORESOURCE_IRQ,
667         },
668 };
669
670 static struct platform_device mv78xx0_uart0 = {
671         .name                   = "serial8250",
672         .id                     = 0,
673         .dev                    = {
674                 .platform_data  = mv78xx0_uart0_data,
675         },
676         .resource               = mv78xx0_uart0_resources,
677         .num_resources          = ARRAY_SIZE(mv78xx0_uart0_resources),
678 };
679
680 void __init mv78xx0_uart0_init(void)
681 {
682         platform_device_register(&mv78xx0_uart0);
683 }
684
685
686 /*****************************************************************************
687  * UART1
688  ****************************************************************************/
689 static struct plat_serial8250_port mv78xx0_uart1_data[] = {
690         {
691                 .mapbase        = UART1_PHYS_BASE,
692                 .membase        = (char *)UART1_VIRT_BASE,
693                 .irq            = IRQ_MV78XX0_UART_1,
694                 .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
695                 .iotype         = UPIO_MEM,
696                 .regshift       = 2,
697                 .uartclk        = 0,
698         }, {
699         },
700 };
701
702 static struct resource mv78xx0_uart1_resources[] = {
703         {
704                 .start          = UART1_PHYS_BASE,
705                 .end            = UART1_PHYS_BASE + 0xff,
706                 .flags          = IORESOURCE_MEM,
707         }, {
708                 .start          = IRQ_MV78XX0_UART_1,
709                 .end            = IRQ_MV78XX0_UART_1,
710                 .flags          = IORESOURCE_IRQ,
711         },
712 };
713
714 static struct platform_device mv78xx0_uart1 = {
715         .name                   = "serial8250",
716         .id                     = 1,
717         .dev                    = {
718                 .platform_data  = mv78xx0_uart1_data,
719         },
720         .resource               = mv78xx0_uart1_resources,
721         .num_resources          = ARRAY_SIZE(mv78xx0_uart1_resources),
722 };
723
724 void __init mv78xx0_uart1_init(void)
725 {
726         platform_device_register(&mv78xx0_uart1);
727 }
728
729
730 /*****************************************************************************
731  * UART2
732  ****************************************************************************/
733 static struct plat_serial8250_port mv78xx0_uart2_data[] = {
734         {
735                 .mapbase        = UART2_PHYS_BASE,
736                 .membase        = (char *)UART2_VIRT_BASE,
737                 .irq            = IRQ_MV78XX0_UART_2,
738                 .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
739                 .iotype         = UPIO_MEM,
740                 .regshift       = 2,
741                 .uartclk        = 0,
742         }, {
743         },
744 };
745
746 static struct resource mv78xx0_uart2_resources[] = {
747         {
748                 .start          = UART2_PHYS_BASE,
749                 .end            = UART2_PHYS_BASE + 0xff,
750                 .flags          = IORESOURCE_MEM,
751         }, {
752                 .start          = IRQ_MV78XX0_UART_2,
753                 .end            = IRQ_MV78XX0_UART_2,
754                 .flags          = IORESOURCE_IRQ,
755         },
756 };
757
758 static struct platform_device mv78xx0_uart2 = {
759         .name                   = "serial8250",
760         .id                     = 2,
761         .dev                    = {
762                 .platform_data  = mv78xx0_uart2_data,
763         },
764         .resource               = mv78xx0_uart2_resources,
765         .num_resources          = ARRAY_SIZE(mv78xx0_uart2_resources),
766 };
767
768 void __init mv78xx0_uart2_init(void)
769 {
770         platform_device_register(&mv78xx0_uart2);
771 }
772
773
774 /*****************************************************************************
775  * UART3
776  ****************************************************************************/
777 static struct plat_serial8250_port mv78xx0_uart3_data[] = {
778         {
779                 .mapbase        = UART3_PHYS_BASE,
780                 .membase        = (char *)UART3_VIRT_BASE,
781                 .irq            = IRQ_MV78XX0_UART_3,
782                 .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
783                 .iotype         = UPIO_MEM,
784                 .regshift       = 2,
785                 .uartclk        = 0,
786         }, {
787         },
788 };
789
790 static struct resource mv78xx0_uart3_resources[] = {
791         {
792                 .start          = UART3_PHYS_BASE,
793                 .end            = UART3_PHYS_BASE + 0xff,
794                 .flags          = IORESOURCE_MEM,
795         }, {
796                 .start          = IRQ_MV78XX0_UART_3,
797                 .end            = IRQ_MV78XX0_UART_3,
798                 .flags          = IORESOURCE_IRQ,
799         },
800 };
801
802 static struct platform_device mv78xx0_uart3 = {
803         .name                   = "serial8250",
804         .id                     = 3,
805         .dev                    = {
806                 .platform_data  = mv78xx0_uart3_data,
807         },
808         .resource               = mv78xx0_uart3_resources,
809         .num_resources          = ARRAY_SIZE(mv78xx0_uart3_resources),
810 };
811
812 void __init mv78xx0_uart3_init(void)
813 {
814         platform_device_register(&mv78xx0_uart3);
815 }
816
817
818 /*****************************************************************************
819  * Time handling
820  ****************************************************************************/
821 static void mv78xx0_timer_init(void)
822 {
823         orion_time_init(IRQ_MV78XX0_TIMER_1, get_tclk());
824 }
825
826 struct sys_timer mv78xx0_timer = {
827         .init = mv78xx0_timer_init,
828 };
829
830
831 /*****************************************************************************
832  * General
833  ****************************************************************************/
834 static char * __init mv78xx0_id(void)
835 {
836         u32 dev, rev;
837
838         mv78xx0_pcie_id(&dev, &rev);
839
840         if (dev == MV78X00_Z0_DEV_ID) {
841                 if (rev == MV78X00_REV_Z0)
842                         return "MV78X00-Z0";
843                 else
844                         return "MV78X00-Rev-Unsupported";
845         } else if (dev == MV78100_DEV_ID) {
846                 if (rev == MV78100_REV_A0)
847                         return "MV78100-A0";
848                 else if (rev == MV78100_REV_A1)
849                         return "MV78100-A1";
850                 else
851                         return "MV78100-Rev-Unsupported";
852         } else if (dev == MV78200_DEV_ID) {
853                 if (rev == MV78100_REV_A0)
854                         return "MV78200-A0";
855                 else
856                         return "MV78200-Rev-Unsupported";
857         } else {
858                 return "Device-Unknown";
859         }
860 }
861
862 static int __init is_l2_writethrough(void)
863 {
864         return !!(readl(CPU_CONTROL) & L2_WRITETHROUGH);
865 }
866
867 void __init mv78xx0_init(void)
868 {
869         int core_index;
870         int hclk;
871         int pclk;
872         int l2clk;
873         int tclk;
874
875         core_index = mv78xx0_core_index();
876         hclk = get_hclk();
877         get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
878         tclk = get_tclk();
879
880         printk(KERN_INFO "%s ", mv78xx0_id());
881         printk("core #%d, ", core_index);
882         printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
883         printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
884         printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
885         printk("TCLK = %dMHz\n", (tclk + 499999) / 1000000);
886
887         mv78xx0_setup_cpu_mbus();
888
889 #ifdef CONFIG_CACHE_FEROCEON_L2
890         feroceon_l2_init(is_l2_writethrough());
891 #endif
892
893         mv78xx0_ge00_shared_data.t_clk = tclk;
894         mv78xx0_ge01_shared_data.t_clk = tclk;
895         mv78xx0_ge10_shared_data.t_clk = tclk;
896         mv78xx0_ge11_shared_data.t_clk = tclk;
897         mv78xx0_uart0_data[0].uartclk = tclk;
898         mv78xx0_uart1_data[0].uartclk = tclk;
899         mv78xx0_uart2_data[0].uartclk = tclk;
900         mv78xx0_uart3_data[0].uartclk = tclk;
901 }