xref: /linux/arch/arm/mach-mv78xx0/common.c (revision 4ee1f6b574765a6c97f945e6b0277e5ccac38cb5)
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 void __init mv78xx0_init_early(void)
822 {
823 	orion_time_set_base(TIMER_VIRT_BASE);
824 }
825 
826 static void mv78xx0_timer_init(void)
827 {
828 	orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
829 			IRQ_MV78XX0_TIMER_1, get_tclk());
830 }
831 
832 struct sys_timer mv78xx0_timer = {
833 	.init = mv78xx0_timer_init,
834 };
835 
836 
837 /*****************************************************************************
838  * General
839  ****************************************************************************/
840 static char * __init mv78xx0_id(void)
841 {
842 	u32 dev, rev;
843 
844 	mv78xx0_pcie_id(&dev, &rev);
845 
846 	if (dev == MV78X00_Z0_DEV_ID) {
847 		if (rev == MV78X00_REV_Z0)
848 			return "MV78X00-Z0";
849 		else
850 			return "MV78X00-Rev-Unsupported";
851 	} else if (dev == MV78100_DEV_ID) {
852 		if (rev == MV78100_REV_A0)
853 			return "MV78100-A0";
854 		else if (rev == MV78100_REV_A1)
855 			return "MV78100-A1";
856 		else
857 			return "MV78100-Rev-Unsupported";
858 	} else if (dev == MV78200_DEV_ID) {
859 		if (rev == MV78100_REV_A0)
860 			return "MV78200-A0";
861 		else
862 			return "MV78200-Rev-Unsupported";
863 	} else {
864 		return "Device-Unknown";
865 	}
866 }
867 
868 static int __init is_l2_writethrough(void)
869 {
870 	return !!(readl(CPU_CONTROL) & L2_WRITETHROUGH);
871 }
872 
873 void __init mv78xx0_init(void)
874 {
875 	int core_index;
876 	int hclk;
877 	int pclk;
878 	int l2clk;
879 	int tclk;
880 
881 	core_index = mv78xx0_core_index();
882 	hclk = get_hclk();
883 	get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
884 	tclk = get_tclk();
885 
886 	printk(KERN_INFO "%s ", mv78xx0_id());
887 	printk("core #%d, ", core_index);
888 	printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
889 	printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
890 	printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
891 	printk("TCLK = %dMHz\n", (tclk + 499999) / 1000000);
892 
893 	mv78xx0_setup_cpu_mbus();
894 
895 #ifdef CONFIG_CACHE_FEROCEON_L2
896 	feroceon_l2_init(is_l2_writethrough());
897 #endif
898 
899 	mv78xx0_ge00_shared_data.t_clk = tclk;
900 	mv78xx0_ge01_shared_data.t_clk = tclk;
901 	mv78xx0_ge10_shared_data.t_clk = tclk;
902 	mv78xx0_ge11_shared_data.t_clk = tclk;
903 	mv78xx0_uart0_data[0].uartclk = tclk;
904 	mv78xx0_uart1_data[0].uartclk = tclk;
905 	mv78xx0_uart2_data[0].uartclk = tclk;
906 	mv78xx0_uart3_data[0].uartclk = tclk;
907 }
908