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