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