xref: /openbmc/linux/arch/arm/mach-mv78xx0/common.c (revision 82ced6fd)
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 };
325 
326 void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
327 {
328 	eth_data->shared = &mv78xx0_ge00_shared;
329 	mv78xx0_ge00.dev.platform_data = eth_data;
330 
331 	platform_device_register(&mv78xx0_ge00_shared);
332 	platform_device_register(&mv78xx0_ge00);
333 }
334 
335 
336 /*****************************************************************************
337  * GE01
338  ****************************************************************************/
339 struct mv643xx_eth_shared_platform_data mv78xx0_ge01_shared_data = {
340 	.t_clk		= 0,
341 	.dram		= &mv78xx0_mbus_dram_info,
342 	.shared_smi	= &mv78xx0_ge00_shared,
343 };
344 
345 static struct resource mv78xx0_ge01_shared_resources[] = {
346 	{
347 		.name	= "ge01 base",
348 		.start	= GE01_PHYS_BASE + 0x2000,
349 		.end	= GE01_PHYS_BASE + 0x3fff,
350 		.flags	= IORESOURCE_MEM,
351 	},
352 };
353 
354 static struct platform_device mv78xx0_ge01_shared = {
355 	.name		= MV643XX_ETH_SHARED_NAME,
356 	.id		= 1,
357 	.dev		= {
358 		.platform_data	= &mv78xx0_ge01_shared_data,
359 	},
360 	.num_resources	= 1,
361 	.resource	= mv78xx0_ge01_shared_resources,
362 };
363 
364 static struct resource mv78xx0_ge01_resources[] = {
365 	{
366 		.name	= "ge01 irq",
367 		.start	= IRQ_MV78XX0_GE01_SUM,
368 		.end	= IRQ_MV78XX0_GE01_SUM,
369 		.flags	= IORESOURCE_IRQ,
370 	},
371 };
372 
373 static struct platform_device mv78xx0_ge01 = {
374 	.name		= MV643XX_ETH_NAME,
375 	.id		= 1,
376 	.num_resources	= 1,
377 	.resource	= mv78xx0_ge01_resources,
378 };
379 
380 void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
381 {
382 	eth_data->shared = &mv78xx0_ge01_shared;
383 	mv78xx0_ge01.dev.platform_data = eth_data;
384 
385 	platform_device_register(&mv78xx0_ge01_shared);
386 	platform_device_register(&mv78xx0_ge01);
387 }
388 
389 
390 /*****************************************************************************
391  * GE10
392  ****************************************************************************/
393 struct mv643xx_eth_shared_platform_data mv78xx0_ge10_shared_data = {
394 	.t_clk		= 0,
395 	.dram		= &mv78xx0_mbus_dram_info,
396 	.shared_smi	= &mv78xx0_ge00_shared,
397 };
398 
399 static struct resource mv78xx0_ge10_shared_resources[] = {
400 	{
401 		.name	= "ge10 base",
402 		.start	= GE10_PHYS_BASE + 0x2000,
403 		.end	= GE10_PHYS_BASE + 0x3fff,
404 		.flags	= IORESOURCE_MEM,
405 	},
406 };
407 
408 static struct platform_device mv78xx0_ge10_shared = {
409 	.name		= MV643XX_ETH_SHARED_NAME,
410 	.id		= 2,
411 	.dev		= {
412 		.platform_data	= &mv78xx0_ge10_shared_data,
413 	},
414 	.num_resources	= 1,
415 	.resource	= mv78xx0_ge10_shared_resources,
416 };
417 
418 static struct resource mv78xx0_ge10_resources[] = {
419 	{
420 		.name	= "ge10 irq",
421 		.start	= IRQ_MV78XX0_GE10_SUM,
422 		.end	= IRQ_MV78XX0_GE10_SUM,
423 		.flags	= IORESOURCE_IRQ,
424 	},
425 };
426 
427 static struct platform_device mv78xx0_ge10 = {
428 	.name		= MV643XX_ETH_NAME,
429 	.id		= 2,
430 	.num_resources	= 1,
431 	.resource	= mv78xx0_ge10_resources,
432 };
433 
434 void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
435 {
436 	u32 dev, rev;
437 
438 	eth_data->shared = &mv78xx0_ge10_shared;
439 	mv78xx0_ge10.dev.platform_data = eth_data;
440 
441 	/*
442 	 * On the Z0, ge10 and ge11 are internally connected back
443 	 * to back, and not brought out.
444 	 */
445 	mv78xx0_pcie_id(&dev, &rev);
446 	if (dev == MV78X00_Z0_DEV_ID) {
447 		eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
448 		eth_data->speed = SPEED_1000;
449 		eth_data->duplex = DUPLEX_FULL;
450 	}
451 
452 	platform_device_register(&mv78xx0_ge10_shared);
453 	platform_device_register(&mv78xx0_ge10);
454 }
455 
456 
457 /*****************************************************************************
458  * GE11
459  ****************************************************************************/
460 struct mv643xx_eth_shared_platform_data mv78xx0_ge11_shared_data = {
461 	.t_clk		= 0,
462 	.dram		= &mv78xx0_mbus_dram_info,
463 	.shared_smi	= &mv78xx0_ge00_shared,
464 };
465 
466 static struct resource mv78xx0_ge11_shared_resources[] = {
467 	{
468 		.name	= "ge11 base",
469 		.start	= GE11_PHYS_BASE + 0x2000,
470 		.end	= GE11_PHYS_BASE + 0x3fff,
471 		.flags	= IORESOURCE_MEM,
472 	},
473 };
474 
475 static struct platform_device mv78xx0_ge11_shared = {
476 	.name		= MV643XX_ETH_SHARED_NAME,
477 	.id		= 3,
478 	.dev		= {
479 		.platform_data	= &mv78xx0_ge11_shared_data,
480 	},
481 	.num_resources	= 1,
482 	.resource	= mv78xx0_ge11_shared_resources,
483 };
484 
485 static struct resource mv78xx0_ge11_resources[] = {
486 	{
487 		.name	= "ge11 irq",
488 		.start	= IRQ_MV78XX0_GE11_SUM,
489 		.end	= IRQ_MV78XX0_GE11_SUM,
490 		.flags	= IORESOURCE_IRQ,
491 	},
492 };
493 
494 static struct platform_device mv78xx0_ge11 = {
495 	.name		= MV643XX_ETH_NAME,
496 	.id		= 3,
497 	.num_resources	= 1,
498 	.resource	= mv78xx0_ge11_resources,
499 };
500 
501 void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
502 {
503 	u32 dev, rev;
504 
505 	eth_data->shared = &mv78xx0_ge11_shared;
506 	mv78xx0_ge11.dev.platform_data = eth_data;
507 
508 	/*
509 	 * On the Z0, ge10 and ge11 are internally connected back
510 	 * to back, and not brought out.
511 	 */
512 	mv78xx0_pcie_id(&dev, &rev);
513 	if (dev == MV78X00_Z0_DEV_ID) {
514 		eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
515 		eth_data->speed = SPEED_1000;
516 		eth_data->duplex = DUPLEX_FULL;
517 	}
518 
519 	platform_device_register(&mv78xx0_ge11_shared);
520 	platform_device_register(&mv78xx0_ge11);
521 }
522 
523 /*****************************************************************************
524  * I2C bus 0
525  ****************************************************************************/
526 
527 static struct mv64xxx_i2c_pdata mv78xx0_i2c_0_pdata = {
528 	.freq_m		= 8, /* assumes 166 MHz TCLK */
529 	.freq_n		= 3,
530 	.timeout	= 1000, /* Default timeout of 1 second */
531 };
532 
533 static struct resource mv78xx0_i2c_0_resources[] = {
534 	{
535 		.name   = "i2c 0 base",
536 		.start  = I2C_0_PHYS_BASE,
537 		.end    = I2C_0_PHYS_BASE + 0x1f,
538 		.flags  = IORESOURCE_MEM,
539 	}, {
540 		.name   = "i2c 0 irq",
541 		.start  = IRQ_MV78XX0_I2C_0,
542 		.end    = IRQ_MV78XX0_I2C_0,
543 		.flags  = IORESOURCE_IRQ,
544 	},
545 };
546 
547 
548 static struct platform_device mv78xx0_i2c_0 = {
549 	.name		= MV64XXX_I2C_CTLR_NAME,
550 	.id		= 0,
551 	.num_resources	= ARRAY_SIZE(mv78xx0_i2c_0_resources),
552 	.resource	= mv78xx0_i2c_0_resources,
553 	.dev		= {
554 		.platform_data	= &mv78xx0_i2c_0_pdata,
555 	},
556 };
557 
558 /*****************************************************************************
559  * I2C bus 1
560  ****************************************************************************/
561 
562 static struct mv64xxx_i2c_pdata mv78xx0_i2c_1_pdata = {
563 	.freq_m		= 8, /* assumes 166 MHz TCLK */
564 	.freq_n		= 3,
565 	.timeout	= 1000, /* Default timeout of 1 second */
566 };
567 
568 static struct resource mv78xx0_i2c_1_resources[] = {
569 	{
570 		.name   = "i2c 1 base",
571 		.start  = I2C_1_PHYS_BASE,
572 		.end    = I2C_1_PHYS_BASE + 0x1f,
573 		.flags  = IORESOURCE_MEM,
574 	}, {
575 		.name   = "i2c 1 irq",
576 		.start  = IRQ_MV78XX0_I2C_1,
577 		.end    = IRQ_MV78XX0_I2C_1,
578 		.flags  = IORESOURCE_IRQ,
579 	},
580 };
581 
582 
583 static struct platform_device mv78xx0_i2c_1 = {
584 	.name		= MV64XXX_I2C_CTLR_NAME,
585 	.id		= 1,
586 	.num_resources	= ARRAY_SIZE(mv78xx0_i2c_1_resources),
587 	.resource	= mv78xx0_i2c_1_resources,
588 	.dev		= {
589 		.platform_data	= &mv78xx0_i2c_1_pdata,
590 	},
591 };
592 
593 void __init mv78xx0_i2c_init(void)
594 {
595 	platform_device_register(&mv78xx0_i2c_0);
596 	platform_device_register(&mv78xx0_i2c_1);
597 }
598 
599 /*****************************************************************************
600  * SATA
601  ****************************************************************************/
602 static struct resource mv78xx0_sata_resources[] = {
603 	{
604 		.name	= "sata base",
605 		.start	= SATA_PHYS_BASE,
606 		.end	= SATA_PHYS_BASE + 0x5000 - 1,
607 		.flags	= IORESOURCE_MEM,
608 	}, {
609 		.name	= "sata irq",
610 		.start	= IRQ_MV78XX0_SATA,
611 		.end	= IRQ_MV78XX0_SATA,
612 		.flags	= IORESOURCE_IRQ,
613 	},
614 };
615 
616 static struct platform_device mv78xx0_sata = {
617 	.name		= "sata_mv",
618 	.id		= 0,
619 	.dev		= {
620 		.coherent_dma_mask	= 0xffffffff,
621 	},
622 	.num_resources	= ARRAY_SIZE(mv78xx0_sata_resources),
623 	.resource	= mv78xx0_sata_resources,
624 };
625 
626 void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data)
627 {
628 	sata_data->dram = &mv78xx0_mbus_dram_info;
629 	mv78xx0_sata.dev.platform_data = sata_data;
630 	platform_device_register(&mv78xx0_sata);
631 }
632 
633 
634 /*****************************************************************************
635  * UART0
636  ****************************************************************************/
637 static struct plat_serial8250_port mv78xx0_uart0_data[] = {
638 	{
639 		.mapbase	= UART0_PHYS_BASE,
640 		.membase	= (char *)UART0_VIRT_BASE,
641 		.irq		= IRQ_MV78XX0_UART_0,
642 		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
643 		.iotype		= UPIO_MEM,
644 		.regshift	= 2,
645 		.uartclk	= 0,
646 	}, {
647 	},
648 };
649 
650 static struct resource mv78xx0_uart0_resources[] = {
651 	{
652 		.start		= UART0_PHYS_BASE,
653 		.end		= UART0_PHYS_BASE + 0xff,
654 		.flags		= IORESOURCE_MEM,
655 	}, {
656 		.start		= IRQ_MV78XX0_UART_0,
657 		.end		= IRQ_MV78XX0_UART_0,
658 		.flags		= IORESOURCE_IRQ,
659 	},
660 };
661 
662 static struct platform_device mv78xx0_uart0 = {
663 	.name			= "serial8250",
664 	.id			= 0,
665 	.dev			= {
666 		.platform_data	= mv78xx0_uart0_data,
667 	},
668 	.resource		= mv78xx0_uart0_resources,
669 	.num_resources		= ARRAY_SIZE(mv78xx0_uart0_resources),
670 };
671 
672 void __init mv78xx0_uart0_init(void)
673 {
674 	platform_device_register(&mv78xx0_uart0);
675 }
676 
677 
678 /*****************************************************************************
679  * UART1
680  ****************************************************************************/
681 static struct plat_serial8250_port mv78xx0_uart1_data[] = {
682 	{
683 		.mapbase	= UART1_PHYS_BASE,
684 		.membase	= (char *)UART1_VIRT_BASE,
685 		.irq		= IRQ_MV78XX0_UART_1,
686 		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
687 		.iotype		= UPIO_MEM,
688 		.regshift	= 2,
689 		.uartclk	= 0,
690 	}, {
691 	},
692 };
693 
694 static struct resource mv78xx0_uart1_resources[] = {
695 	{
696 		.start		= UART1_PHYS_BASE,
697 		.end		= UART1_PHYS_BASE + 0xff,
698 		.flags		= IORESOURCE_MEM,
699 	}, {
700 		.start		= IRQ_MV78XX0_UART_1,
701 		.end		= IRQ_MV78XX0_UART_1,
702 		.flags		= IORESOURCE_IRQ,
703 	},
704 };
705 
706 static struct platform_device mv78xx0_uart1 = {
707 	.name			= "serial8250",
708 	.id			= 1,
709 	.dev			= {
710 		.platform_data	= mv78xx0_uart1_data,
711 	},
712 	.resource		= mv78xx0_uart1_resources,
713 	.num_resources		= ARRAY_SIZE(mv78xx0_uart1_resources),
714 };
715 
716 void __init mv78xx0_uart1_init(void)
717 {
718 	platform_device_register(&mv78xx0_uart1);
719 }
720 
721 
722 /*****************************************************************************
723  * UART2
724  ****************************************************************************/
725 static struct plat_serial8250_port mv78xx0_uart2_data[] = {
726 	{
727 		.mapbase	= UART2_PHYS_BASE,
728 		.membase	= (char *)UART2_VIRT_BASE,
729 		.irq		= IRQ_MV78XX0_UART_2,
730 		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
731 		.iotype		= UPIO_MEM,
732 		.regshift	= 2,
733 		.uartclk	= 0,
734 	}, {
735 	},
736 };
737 
738 static struct resource mv78xx0_uart2_resources[] = {
739 	{
740 		.start		= UART2_PHYS_BASE,
741 		.end		= UART2_PHYS_BASE + 0xff,
742 		.flags		= IORESOURCE_MEM,
743 	}, {
744 		.start		= IRQ_MV78XX0_UART_2,
745 		.end		= IRQ_MV78XX0_UART_2,
746 		.flags		= IORESOURCE_IRQ,
747 	},
748 };
749 
750 static struct platform_device mv78xx0_uart2 = {
751 	.name			= "serial8250",
752 	.id			= 2,
753 	.dev			= {
754 		.platform_data	= mv78xx0_uart2_data,
755 	},
756 	.resource		= mv78xx0_uart2_resources,
757 	.num_resources		= ARRAY_SIZE(mv78xx0_uart2_resources),
758 };
759 
760 void __init mv78xx0_uart2_init(void)
761 {
762 	platform_device_register(&mv78xx0_uart2);
763 }
764 
765 
766 /*****************************************************************************
767  * UART3
768  ****************************************************************************/
769 static struct plat_serial8250_port mv78xx0_uart3_data[] = {
770 	{
771 		.mapbase	= UART3_PHYS_BASE,
772 		.membase	= (char *)UART3_VIRT_BASE,
773 		.irq		= IRQ_MV78XX0_UART_3,
774 		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
775 		.iotype		= UPIO_MEM,
776 		.regshift	= 2,
777 		.uartclk	= 0,
778 	}, {
779 	},
780 };
781 
782 static struct resource mv78xx0_uart3_resources[] = {
783 	{
784 		.start		= UART3_PHYS_BASE,
785 		.end		= UART3_PHYS_BASE + 0xff,
786 		.flags		= IORESOURCE_MEM,
787 	}, {
788 		.start		= IRQ_MV78XX0_UART_3,
789 		.end		= IRQ_MV78XX0_UART_3,
790 		.flags		= IORESOURCE_IRQ,
791 	},
792 };
793 
794 static struct platform_device mv78xx0_uart3 = {
795 	.name			= "serial8250",
796 	.id			= 3,
797 	.dev			= {
798 		.platform_data	= mv78xx0_uart3_data,
799 	},
800 	.resource		= mv78xx0_uart3_resources,
801 	.num_resources		= ARRAY_SIZE(mv78xx0_uart3_resources),
802 };
803 
804 void __init mv78xx0_uart3_init(void)
805 {
806 	platform_device_register(&mv78xx0_uart3);
807 }
808 
809 
810 /*****************************************************************************
811  * Time handling
812  ****************************************************************************/
813 static void mv78xx0_timer_init(void)
814 {
815 	orion_time_init(IRQ_MV78XX0_TIMER_1, get_tclk());
816 }
817 
818 struct sys_timer mv78xx0_timer = {
819 	.init = mv78xx0_timer_init,
820 };
821 
822 
823 /*****************************************************************************
824  * General
825  ****************************************************************************/
826 static char * __init mv78xx0_id(void)
827 {
828 	u32 dev, rev;
829 
830 	mv78xx0_pcie_id(&dev, &rev);
831 
832 	if (dev == MV78X00_Z0_DEV_ID) {
833 		if (rev == MV78X00_REV_Z0)
834 			return "MV78X00-Z0";
835 		else
836 			return "MV78X00-Rev-Unsupported";
837 	} else if (dev == MV78100_DEV_ID) {
838 		if (rev == MV78100_REV_A0)
839 			return "MV78100-A0";
840 		else
841 			return "MV78100-Rev-Unsupported";
842 	} else if (dev == MV78200_DEV_ID) {
843 		if (rev == MV78100_REV_A0)
844 			return "MV78200-A0";
845 		else
846 			return "MV78200-Rev-Unsupported";
847 	} else {
848 		return "Device-Unknown";
849 	}
850 }
851 
852 static int __init is_l2_writethrough(void)
853 {
854 	return !!(readl(CPU_CONTROL) & L2_WRITETHROUGH);
855 }
856 
857 void __init mv78xx0_init(void)
858 {
859 	int core_index;
860 	int hclk;
861 	int pclk;
862 	int l2clk;
863 	int tclk;
864 
865 	core_index = mv78xx0_core_index();
866 	hclk = get_hclk();
867 	get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
868 	tclk = get_tclk();
869 
870 	printk(KERN_INFO "%s ", mv78xx0_id());
871 	printk("core #%d, ", core_index);
872 	printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
873 	printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
874 	printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
875 	printk("TCLK = %dMHz\n", (tclk + 499999) / 1000000);
876 
877 	mv78xx0_setup_cpu_mbus();
878 
879 #ifdef CONFIG_CACHE_FEROCEON_L2
880 	feroceon_l2_init(is_l2_writethrough());
881 #endif
882 
883 	mv78xx0_ge00_shared_data.t_clk = tclk;
884 	mv78xx0_ge01_shared_data.t_clk = tclk;
885 	mv78xx0_ge10_shared_data.t_clk = tclk;
886 	mv78xx0_ge11_shared_data.t_clk = tclk;
887 	mv78xx0_uart0_data[0].uartclk = tclk;
888 	mv78xx0_uart1_data[0].uartclk = tclk;
889 	mv78xx0_uart2_data[0].uartclk = tclk;
890 	mv78xx0_uart3_data[0].uartclk = tclk;
891 }
892