2 * arch/arm/mach-kirkwood/common.c
4 * Core functions for Marvell Kirkwood SoCs
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.
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/spi/orion_spi.h>
22 #include <asm/timex.h>
23 #include <asm/mach/map.h>
24 #include <asm/mach/time.h>
25 #include <mach/kirkwood.h>
26 #include <plat/cache-feroceon-l2.h>
27 #include <plat/ehci-orion.h>
28 #include <plat/mvsdio.h>
29 #include <plat/mv_xor.h>
30 #include <plat/orion_nand.h>
31 #include <plat/time.h>
34 /*****************************************************************************
36 ****************************************************************************/
37 static struct map_desc kirkwood_io_desc
[] __initdata
= {
39 .virtual = KIRKWOOD_PCIE_IO_VIRT_BASE
,
40 .pfn
= __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE
),
41 .length
= KIRKWOOD_PCIE_IO_SIZE
,
44 .virtual = KIRKWOOD_REGS_VIRT_BASE
,
45 .pfn
= __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE
),
46 .length
= KIRKWOOD_REGS_SIZE
,
51 void __init
kirkwood_map_io(void)
53 iotable_init(kirkwood_io_desc
, ARRAY_SIZE(kirkwood_io_desc
));
57 /*****************************************************************************
59 ****************************************************************************/
60 static struct orion_ehci_data kirkwood_ehci_data
= {
61 .dram
= &kirkwood_mbus_dram_info
,
62 .phy_version
= EHCI_PHY_NA
,
65 static u64 ehci_dmamask
= 0xffffffffUL
;
68 /*****************************************************************************
70 ****************************************************************************/
71 static struct resource kirkwood_ehci_resources
[] = {
73 .start
= USB_PHYS_BASE
,
74 .end
= USB_PHYS_BASE
+ 0x0fff,
75 .flags
= IORESOURCE_MEM
,
77 .start
= IRQ_KIRKWOOD_USB
,
78 .end
= IRQ_KIRKWOOD_USB
,
79 .flags
= IORESOURCE_IRQ
,
83 static struct platform_device kirkwood_ehci
= {
87 .dma_mask
= &ehci_dmamask
,
88 .coherent_dma_mask
= 0xffffffff,
89 .platform_data
= &kirkwood_ehci_data
,
91 .resource
= kirkwood_ehci_resources
,
92 .num_resources
= ARRAY_SIZE(kirkwood_ehci_resources
),
95 void __init
kirkwood_ehci_init(void)
97 platform_device_register(&kirkwood_ehci
);
101 /*****************************************************************************
103 ****************************************************************************/
104 struct mv643xx_eth_shared_platform_data kirkwood_ge00_shared_data
= {
105 .dram
= &kirkwood_mbus_dram_info
,
108 static struct resource kirkwood_ge00_shared_resources
[] = {
111 .start
= GE00_PHYS_BASE
+ 0x2000,
112 .end
= GE00_PHYS_BASE
+ 0x3fff,
113 .flags
= IORESOURCE_MEM
,
115 .name
= "ge00 err irq",
116 .start
= IRQ_KIRKWOOD_GE00_ERR
,
117 .end
= IRQ_KIRKWOOD_GE00_ERR
,
118 .flags
= IORESOURCE_IRQ
,
122 static struct platform_device kirkwood_ge00_shared
= {
123 .name
= MV643XX_ETH_SHARED_NAME
,
126 .platform_data
= &kirkwood_ge00_shared_data
,
128 .num_resources
= ARRAY_SIZE(kirkwood_ge00_shared_resources
),
129 .resource
= kirkwood_ge00_shared_resources
,
132 static struct resource kirkwood_ge00_resources
[] = {
135 .start
= IRQ_KIRKWOOD_GE00_SUM
,
136 .end
= IRQ_KIRKWOOD_GE00_SUM
,
137 .flags
= IORESOURCE_IRQ
,
141 static struct platform_device kirkwood_ge00
= {
142 .name
= MV643XX_ETH_NAME
,
145 .resource
= kirkwood_ge00_resources
,
148 void __init
kirkwood_ge00_init(struct mv643xx_eth_platform_data
*eth_data
)
150 eth_data
->shared
= &kirkwood_ge00_shared
;
151 kirkwood_ge00
.dev
.platform_data
= eth_data
;
153 platform_device_register(&kirkwood_ge00_shared
);
154 platform_device_register(&kirkwood_ge00
);
158 /*****************************************************************************
160 ****************************************************************************/
161 struct mv643xx_eth_shared_platform_data kirkwood_ge01_shared_data
= {
162 .dram
= &kirkwood_mbus_dram_info
,
163 .shared_smi
= &kirkwood_ge00_shared
,
166 static struct resource kirkwood_ge01_shared_resources
[] = {
169 .start
= GE01_PHYS_BASE
+ 0x2000,
170 .end
= GE01_PHYS_BASE
+ 0x3fff,
171 .flags
= IORESOURCE_MEM
,
173 .name
= "ge01 err irq",
174 .start
= IRQ_KIRKWOOD_GE01_ERR
,
175 .end
= IRQ_KIRKWOOD_GE01_ERR
,
176 .flags
= IORESOURCE_IRQ
,
180 static struct platform_device kirkwood_ge01_shared
= {
181 .name
= MV643XX_ETH_SHARED_NAME
,
184 .platform_data
= &kirkwood_ge01_shared_data
,
186 .num_resources
= ARRAY_SIZE(kirkwood_ge01_shared_resources
),
187 .resource
= kirkwood_ge01_shared_resources
,
190 static struct resource kirkwood_ge01_resources
[] = {
193 .start
= IRQ_KIRKWOOD_GE01_SUM
,
194 .end
= IRQ_KIRKWOOD_GE01_SUM
,
195 .flags
= IORESOURCE_IRQ
,
199 static struct platform_device kirkwood_ge01
= {
200 .name
= MV643XX_ETH_NAME
,
203 .resource
= kirkwood_ge01_resources
,
206 void __init
kirkwood_ge01_init(struct mv643xx_eth_platform_data
*eth_data
)
208 eth_data
->shared
= &kirkwood_ge01_shared
;
209 kirkwood_ge01
.dev
.platform_data
= eth_data
;
211 platform_device_register(&kirkwood_ge01_shared
);
212 platform_device_register(&kirkwood_ge01
);
216 /*****************************************************************************
218 ****************************************************************************/
219 static struct resource kirkwood_switch_resources
[] = {
223 .flags
= IORESOURCE_IRQ
,
227 static struct platform_device kirkwood_switch_device
= {
231 .resource
= kirkwood_switch_resources
,
234 void __init
kirkwood_ge00_switch_init(struct dsa_platform_data
*d
, int irq
)
239 kirkwood_switch_resources
[0].start
= irq
;
240 kirkwood_switch_resources
[0].end
= irq
;
241 kirkwood_switch_device
.num_resources
= 1;
244 d
->netdev
= &kirkwood_ge00
.dev
;
245 for (i
= 0; i
< d
->nr_chips
; i
++)
246 d
->chip
[i
].mii_bus
= &kirkwood_ge00_shared
.dev
;
247 kirkwood_switch_device
.dev
.platform_data
= d
;
249 platform_device_register(&kirkwood_switch_device
);
253 /*****************************************************************************
255 ****************************************************************************/
256 static struct resource kirkwood_rtc_resource
= {
257 .start
= RTC_PHYS_BASE
,
258 .end
= RTC_PHYS_BASE
+ SZ_16
- 1,
259 .flags
= IORESOURCE_MEM
,
262 static void __init
kirkwood_rtc_init(void)
264 platform_device_register_simple("rtc-mv", -1, &kirkwood_rtc_resource
, 1);
268 /*****************************************************************************
270 ****************************************************************************/
271 static struct resource kirkwood_sata_resources
[] = {
274 .start
= SATA_PHYS_BASE
,
275 .end
= SATA_PHYS_BASE
+ 0x5000 - 1,
276 .flags
= IORESOURCE_MEM
,
279 .start
= IRQ_KIRKWOOD_SATA
,
280 .end
= IRQ_KIRKWOOD_SATA
,
281 .flags
= IORESOURCE_IRQ
,
285 static struct platform_device kirkwood_sata
= {
289 .coherent_dma_mask
= 0xffffffff,
291 .num_resources
= ARRAY_SIZE(kirkwood_sata_resources
),
292 .resource
= kirkwood_sata_resources
,
295 void __init
kirkwood_sata_init(struct mv_sata_platform_data
*sata_data
)
297 sata_data
->dram
= &kirkwood_mbus_dram_info
;
298 kirkwood_sata
.dev
.platform_data
= sata_data
;
299 platform_device_register(&kirkwood_sata
);
303 /*****************************************************************************
305 ****************************************************************************/
306 static struct resource mvsdio_resources
[] = {
308 .start
= SDIO_PHYS_BASE
,
309 .end
= SDIO_PHYS_BASE
+ SZ_1K
- 1,
310 .flags
= IORESOURCE_MEM
,
313 .start
= IRQ_KIRKWOOD_SDIO
,
314 .end
= IRQ_KIRKWOOD_SDIO
,
315 .flags
= IORESOURCE_IRQ
,
319 static u64 mvsdio_dmamask
= 0xffffffffUL
;
321 static struct platform_device kirkwood_sdio
= {
325 .dma_mask
= &mvsdio_dmamask
,
326 .coherent_dma_mask
= 0xffffffff,
328 .num_resources
= ARRAY_SIZE(mvsdio_resources
),
329 .resource
= mvsdio_resources
,
332 void __init
kirkwood_sdio_init(struct mvsdio_platform_data
*mvsdio_data
)
336 kirkwood_pcie_id(&dev
, &rev
);
337 if (rev
== 0) /* catch all Kirkwood Z0's */
338 mvsdio_data
->clock
= 100000000;
340 mvsdio_data
->clock
= 200000000;
341 mvsdio_data
->dram
= &kirkwood_mbus_dram_info
;
342 kirkwood_sdio
.dev
.platform_data
= mvsdio_data
;
343 platform_device_register(&kirkwood_sdio
);
347 /*****************************************************************************
349 ****************************************************************************/
350 static struct orion_spi_info kirkwood_spi_plat_data
= {
353 static struct resource kirkwood_spi_resources
[] = {
355 .start
= SPI_PHYS_BASE
,
356 .end
= SPI_PHYS_BASE
+ SZ_512
- 1,
357 .flags
= IORESOURCE_MEM
,
361 static struct platform_device kirkwood_spi
= {
364 .resource
= kirkwood_spi_resources
,
366 .platform_data
= &kirkwood_spi_plat_data
,
368 .num_resources
= ARRAY_SIZE(kirkwood_spi_resources
),
371 void __init
kirkwood_spi_init()
373 platform_device_register(&kirkwood_spi
);
377 /*****************************************************************************
379 ****************************************************************************/
380 static struct mv64xxx_i2c_pdata kirkwood_i2c_pdata
= {
381 .freq_m
= 8, /* assumes 166 MHz TCLK */
383 .timeout
= 1000, /* Default timeout of 1 second */
386 static struct resource kirkwood_i2c_resources
[] = {
389 .start
= I2C_PHYS_BASE
,
390 .end
= I2C_PHYS_BASE
+ 0x1f,
391 .flags
= IORESOURCE_MEM
,
394 .start
= IRQ_KIRKWOOD_TWSI
,
395 .end
= IRQ_KIRKWOOD_TWSI
,
396 .flags
= IORESOURCE_IRQ
,
400 static struct platform_device kirkwood_i2c
= {
401 .name
= MV64XXX_I2C_CTLR_NAME
,
403 .num_resources
= ARRAY_SIZE(kirkwood_i2c_resources
),
404 .resource
= kirkwood_i2c_resources
,
406 .platform_data
= &kirkwood_i2c_pdata
,
410 void __init
kirkwood_i2c_init(void)
412 platform_device_register(&kirkwood_i2c
);
416 /*****************************************************************************
418 ****************************************************************************/
419 static struct plat_serial8250_port kirkwood_uart0_data
[] = {
421 .mapbase
= UART0_PHYS_BASE
,
422 .membase
= (char *)UART0_VIRT_BASE
,
423 .irq
= IRQ_KIRKWOOD_UART_0
,
424 .flags
= UPF_SKIP_TEST
| UPF_BOOT_AUTOCONF
,
432 static struct resource kirkwood_uart0_resources
[] = {
434 .start
= UART0_PHYS_BASE
,
435 .end
= UART0_PHYS_BASE
+ 0xff,
436 .flags
= IORESOURCE_MEM
,
438 .start
= IRQ_KIRKWOOD_UART_0
,
439 .end
= IRQ_KIRKWOOD_UART_0
,
440 .flags
= IORESOURCE_IRQ
,
444 static struct platform_device kirkwood_uart0
= {
445 .name
= "serial8250",
448 .platform_data
= kirkwood_uart0_data
,
450 .resource
= kirkwood_uart0_resources
,
451 .num_resources
= ARRAY_SIZE(kirkwood_uart0_resources
),
454 void __init
kirkwood_uart0_init(void)
456 platform_device_register(&kirkwood_uart0
);
460 /*****************************************************************************
462 ****************************************************************************/
463 static struct plat_serial8250_port kirkwood_uart1_data
[] = {
465 .mapbase
= UART1_PHYS_BASE
,
466 .membase
= (char *)UART1_VIRT_BASE
,
467 .irq
= IRQ_KIRKWOOD_UART_1
,
468 .flags
= UPF_SKIP_TEST
| UPF_BOOT_AUTOCONF
,
476 static struct resource kirkwood_uart1_resources
[] = {
478 .start
= UART1_PHYS_BASE
,
479 .end
= UART1_PHYS_BASE
+ 0xff,
480 .flags
= IORESOURCE_MEM
,
482 .start
= IRQ_KIRKWOOD_UART_1
,
483 .end
= IRQ_KIRKWOOD_UART_1
,
484 .flags
= IORESOURCE_IRQ
,
488 static struct platform_device kirkwood_uart1
= {
489 .name
= "serial8250",
492 .platform_data
= kirkwood_uart1_data
,
494 .resource
= kirkwood_uart1_resources
,
495 .num_resources
= ARRAY_SIZE(kirkwood_uart1_resources
),
498 void __init
kirkwood_uart1_init(void)
500 platform_device_register(&kirkwood_uart1
);
504 /*****************************************************************************
506 ****************************************************************************/
507 static struct mv_xor_platform_shared_data kirkwood_xor_shared_data
= {
508 .dram
= &kirkwood_mbus_dram_info
,
511 static u64 kirkwood_xor_dmamask
= DMA_32BIT_MASK
;
514 /*****************************************************************************
516 ****************************************************************************/
517 static struct resource kirkwood_xor0_shared_resources
[] = {
520 .start
= XOR0_PHYS_BASE
,
521 .end
= XOR0_PHYS_BASE
+ 0xff,
522 .flags
= IORESOURCE_MEM
,
524 .name
= "xor 0 high",
525 .start
= XOR0_HIGH_PHYS_BASE
,
526 .end
= XOR0_HIGH_PHYS_BASE
+ 0xff,
527 .flags
= IORESOURCE_MEM
,
531 static struct platform_device kirkwood_xor0_shared
= {
532 .name
= MV_XOR_SHARED_NAME
,
535 .platform_data
= &kirkwood_xor_shared_data
,
537 .num_resources
= ARRAY_SIZE(kirkwood_xor0_shared_resources
),
538 .resource
= kirkwood_xor0_shared_resources
,
541 static struct resource kirkwood_xor00_resources
[] = {
543 .start
= IRQ_KIRKWOOD_XOR_00
,
544 .end
= IRQ_KIRKWOOD_XOR_00
,
545 .flags
= IORESOURCE_IRQ
,
549 static struct mv_xor_platform_data kirkwood_xor00_data
= {
550 .shared
= &kirkwood_xor0_shared
,
552 .pool_size
= PAGE_SIZE
,
555 static struct platform_device kirkwood_xor00_channel
= {
558 .num_resources
= ARRAY_SIZE(kirkwood_xor00_resources
),
559 .resource
= kirkwood_xor00_resources
,
561 .dma_mask
= &kirkwood_xor_dmamask
,
562 .coherent_dma_mask
= DMA_64BIT_MASK
,
563 .platform_data
= (void *)&kirkwood_xor00_data
,
567 static struct resource kirkwood_xor01_resources
[] = {
569 .start
= IRQ_KIRKWOOD_XOR_01
,
570 .end
= IRQ_KIRKWOOD_XOR_01
,
571 .flags
= IORESOURCE_IRQ
,
575 static struct mv_xor_platform_data kirkwood_xor01_data
= {
576 .shared
= &kirkwood_xor0_shared
,
578 .pool_size
= PAGE_SIZE
,
581 static struct platform_device kirkwood_xor01_channel
= {
584 .num_resources
= ARRAY_SIZE(kirkwood_xor01_resources
),
585 .resource
= kirkwood_xor01_resources
,
587 .dma_mask
= &kirkwood_xor_dmamask
,
588 .coherent_dma_mask
= DMA_64BIT_MASK
,
589 .platform_data
= (void *)&kirkwood_xor01_data
,
593 static void __init
kirkwood_xor0_init(void)
595 platform_device_register(&kirkwood_xor0_shared
);
598 * two engines can't do memset simultaneously, this limitation
599 * satisfied by removing memset support from one of the engines.
601 dma_cap_set(DMA_MEMCPY
, kirkwood_xor00_data
.cap_mask
);
602 dma_cap_set(DMA_XOR
, kirkwood_xor00_data
.cap_mask
);
603 platform_device_register(&kirkwood_xor00_channel
);
605 dma_cap_set(DMA_MEMCPY
, kirkwood_xor01_data
.cap_mask
);
606 dma_cap_set(DMA_MEMSET
, kirkwood_xor01_data
.cap_mask
);
607 dma_cap_set(DMA_XOR
, kirkwood_xor01_data
.cap_mask
);
608 platform_device_register(&kirkwood_xor01_channel
);
612 /*****************************************************************************
614 ****************************************************************************/
615 static struct resource kirkwood_xor1_shared_resources
[] = {
618 .start
= XOR1_PHYS_BASE
,
619 .end
= XOR1_PHYS_BASE
+ 0xff,
620 .flags
= IORESOURCE_MEM
,
622 .name
= "xor 1 high",
623 .start
= XOR1_HIGH_PHYS_BASE
,
624 .end
= XOR1_HIGH_PHYS_BASE
+ 0xff,
625 .flags
= IORESOURCE_MEM
,
629 static struct platform_device kirkwood_xor1_shared
= {
630 .name
= MV_XOR_SHARED_NAME
,
633 .platform_data
= &kirkwood_xor_shared_data
,
635 .num_resources
= ARRAY_SIZE(kirkwood_xor1_shared_resources
),
636 .resource
= kirkwood_xor1_shared_resources
,
639 static struct resource kirkwood_xor10_resources
[] = {
641 .start
= IRQ_KIRKWOOD_XOR_10
,
642 .end
= IRQ_KIRKWOOD_XOR_10
,
643 .flags
= IORESOURCE_IRQ
,
647 static struct mv_xor_platform_data kirkwood_xor10_data
= {
648 .shared
= &kirkwood_xor1_shared
,
650 .pool_size
= PAGE_SIZE
,
653 static struct platform_device kirkwood_xor10_channel
= {
656 .num_resources
= ARRAY_SIZE(kirkwood_xor10_resources
),
657 .resource
= kirkwood_xor10_resources
,
659 .dma_mask
= &kirkwood_xor_dmamask
,
660 .coherent_dma_mask
= DMA_64BIT_MASK
,
661 .platform_data
= (void *)&kirkwood_xor10_data
,
665 static struct resource kirkwood_xor11_resources
[] = {
667 .start
= IRQ_KIRKWOOD_XOR_11
,
668 .end
= IRQ_KIRKWOOD_XOR_11
,
669 .flags
= IORESOURCE_IRQ
,
673 static struct mv_xor_platform_data kirkwood_xor11_data
= {
674 .shared
= &kirkwood_xor1_shared
,
676 .pool_size
= PAGE_SIZE
,
679 static struct platform_device kirkwood_xor11_channel
= {
682 .num_resources
= ARRAY_SIZE(kirkwood_xor11_resources
),
683 .resource
= kirkwood_xor11_resources
,
685 .dma_mask
= &kirkwood_xor_dmamask
,
686 .coherent_dma_mask
= DMA_64BIT_MASK
,
687 .platform_data
= (void *)&kirkwood_xor11_data
,
691 static void __init
kirkwood_xor1_init(void)
693 platform_device_register(&kirkwood_xor1_shared
);
696 * two engines can't do memset simultaneously, this limitation
697 * satisfied by removing memset support from one of the engines.
699 dma_cap_set(DMA_MEMCPY
, kirkwood_xor10_data
.cap_mask
);
700 dma_cap_set(DMA_XOR
, kirkwood_xor10_data
.cap_mask
);
701 platform_device_register(&kirkwood_xor10_channel
);
703 dma_cap_set(DMA_MEMCPY
, kirkwood_xor11_data
.cap_mask
);
704 dma_cap_set(DMA_MEMSET
, kirkwood_xor11_data
.cap_mask
);
705 dma_cap_set(DMA_XOR
, kirkwood_xor11_data
.cap_mask
);
706 platform_device_register(&kirkwood_xor11_channel
);
710 /*****************************************************************************
712 ****************************************************************************/
715 int __init
kirkwood_find_tclk(void)
719 kirkwood_pcie_id(&dev
, &rev
);
720 if (dev
== MV88F6281_DEV_ID
&& rev
== MV88F6281_REV_A0
)
726 static void kirkwood_timer_init(void)
728 kirkwood_tclk
= kirkwood_find_tclk();
729 orion_time_init(IRQ_KIRKWOOD_BRIDGE
, kirkwood_tclk
);
732 struct sys_timer kirkwood_timer
= {
733 .init
= kirkwood_timer_init
,
737 /*****************************************************************************
739 ****************************************************************************/
741 * Identify device ID and revision.
743 static char * __init
kirkwood_id(void)
747 kirkwood_pcie_id(&dev
, &rev
);
749 if (dev
== MV88F6281_DEV_ID
) {
750 if (rev
== MV88F6281_REV_Z0
)
751 return "MV88F6281-Z0";
752 else if (rev
== MV88F6281_REV_A0
)
753 return "MV88F6281-A0";
755 return "MV88F6281-Rev-Unsupported";
756 } else if (dev
== MV88F6192_DEV_ID
) {
757 if (rev
== MV88F6192_REV_Z0
)
758 return "MV88F6192-Z0";
759 else if (rev
== MV88F6192_REV_A0
)
760 return "MV88F6192-A0";
762 return "MV88F6192-Rev-Unsupported";
763 } else if (dev
== MV88F6180_DEV_ID
) {
764 if (rev
== MV88F6180_REV_A0
)
765 return "MV88F6180-Rev-A0";
767 return "MV88F6180-Rev-Unsupported";
769 return "Device-Unknown";
773 static void __init
kirkwood_l2_init(void)
775 #ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH
776 writel(readl(L2_CONFIG_REG
) | L2_WRITETHROUGH
, L2_CONFIG_REG
);
779 writel(readl(L2_CONFIG_REG
) & ~L2_WRITETHROUGH
, L2_CONFIG_REG
);
784 void __init
kirkwood_init(void)
786 printk(KERN_INFO
"Kirkwood: %s, TCLK=%d.\n",
787 kirkwood_id(), kirkwood_tclk
);
788 kirkwood_ge00_shared_data
.t_clk
= kirkwood_tclk
;
789 kirkwood_ge01_shared_data
.t_clk
= kirkwood_tclk
;
790 kirkwood_spi_plat_data
.tclk
= kirkwood_tclk
;
791 kirkwood_uart0_data
[0].uartclk
= kirkwood_tclk
;
792 kirkwood_uart1_data
[0].uartclk
= kirkwood_tclk
;
794 kirkwood_setup_cpu_mbus();
796 #ifdef CONFIG_CACHE_FEROCEON_L2
800 /* internal devices that every board has */
802 kirkwood_xor0_init();
803 kirkwood_xor1_init();