diff options
28 files changed, 1088 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt b/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt new file mode 100644 index 000000000000..70c0dc5f00ed --- /dev/null +++ b/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt | |||
@@ -0,0 +1,23 @@ | |||
1 | Marvell Armada 370 and Armada XP Interrupt Controller | ||
2 | ----------------------------------------------------- | ||
3 | |||
4 | Required properties: | ||
5 | - compatible: Should be "marvell,mpic" | ||
6 | - interrupt-controller: Identifies the node as an interrupt controller. | ||
7 | - #interrupt-cells: The number of cells to define the interrupts. Should be 1. | ||
8 | The cell is the IRQ number | ||
9 | - reg: Should contain PMIC registers location and length. First pair | ||
10 | for the main interrupt registers, second pair for the per-CPU | ||
11 | interrupt registers | ||
12 | |||
13 | Example: | ||
14 | |||
15 | mpic: interrupt-controller@d0020000 { | ||
16 | compatible = "marvell,mpic"; | ||
17 | #interrupt-cells = <1>; | ||
18 | #address-cells = <1>; | ||
19 | #size-cells = <1>; | ||
20 | interrupt-controller; | ||
21 | reg = <0xd0020000 0x1000>, | ||
22 | <0xd0021000 0x1000>; | ||
23 | }; | ||
diff --git a/Documentation/devicetree/bindings/arm/armada-370-xp-timer.txt b/Documentation/devicetree/bindings/arm/armada-370-xp-timer.txt new file mode 100644 index 000000000000..8b6ea2267c94 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/armada-370-xp-timer.txt | |||
@@ -0,0 +1,11 @@ | |||
1 | Marvell Armada 370 and Armada XP Global Timers | ||
2 | ---------------------------------------------- | ||
3 | |||
4 | Required properties: | ||
5 | - compatible: Should be "marvell,armada-370-xp-timer" | ||
6 | - interrupts: Should contain the list of Global Timer interrupts | ||
7 | - reg: Should contain the base address of the Global Timer registers | ||
8 | |||
9 | Optional properties: | ||
10 | - marvell,timer-25Mhz: Tells whether the Global timer supports the 25 | ||
11 | Mhz fixed mode (available on Armada XP and not on Armada 370) | ||
diff --git a/Documentation/devicetree/bindings/arm/armada-370-xp.txt b/Documentation/devicetree/bindings/arm/armada-370-xp.txt new file mode 100644 index 000000000000..c6ed90ea6e17 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/armada-370-xp.txt | |||
@@ -0,0 +1,24 @@ | |||
1 | Marvell Armada 370 and Armada XP Platforms Device Tree Bindings | ||
2 | --------------------------------------------------------------- | ||
3 | |||
4 | Boards with a SoC of the Marvell Armada 370 and Armada XP families | ||
5 | shall have the following property: | ||
6 | |||
7 | Required root node property: | ||
8 | |||
9 | compatible: must contain "marvell,armada-370-xp" | ||
10 | |||
11 | In addition, boards using the Marvell Armada 370 SoC shall have the | ||
12 | following property: | ||
13 | |||
14 | Required root node property: | ||
15 | |||
16 | compatible: must contain "marvell,armada370" | ||
17 | |||
18 | In addition, boards using the Marvell Armada XP SoC shall have the | ||
19 | following property: | ||
20 | |||
21 | Required root node property: | ||
22 | |||
23 | compatible: must contain "marvell,armadaxp" | ||
24 | |||
diff --git a/Documentation/devicetree/bindings/arm/mvebu-system-controller.txt b/Documentation/devicetree/bindings/arm/mvebu-system-controller.txt new file mode 100644 index 000000000000..081c6a786c8a --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mvebu-system-controller.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | MVEBU System Controller | ||
2 | ----------------------- | ||
3 | MVEBU (Marvell SOCs: Armada 370/XP, Dove, mv78xx0, Kirkwood, Orion5x) | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible: one of: | ||
8 | - "marvell,orion-system-controller" | ||
9 | - "marvell,armada-370-xp-system-controller" | ||
10 | - reg: Should contain system controller registers location and length. | ||
11 | |||
12 | Example: | ||
13 | |||
14 | system-controller@d0018200 { | ||
15 | compatible = "marvell,armada-370-xp-system-controller"; | ||
16 | reg = <0xd0018200 0x500>; | ||
17 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index eb22272b2116..b8a65fbf0473 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -894,6 +894,14 @@ ARM/MAGICIAN MACHINE SUPPORT | |||
894 | M: Philipp Zabel <philipp.zabel@gmail.com> | 894 | M: Philipp Zabel <philipp.zabel@gmail.com> |
895 | S: Maintained | 895 | S: Maintained |
896 | 896 | ||
897 | ARM/Marvell Armada 370 and Armada XP SOC support | ||
898 | M: Jason Cooper <jason@lakedaemon.net> | ||
899 | M: Andrew Lunn <andrew@lunn.ch> | ||
900 | M: Gregory Clement <gregory.clement@free-electrons.com> | ||
901 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
902 | S: Maintained | ||
903 | F: arch/arm/mach-mvebu/ | ||
904 | |||
897 | ARM/Marvell Dove/Kirkwood/MV78xx0/Orion SOC support | 905 | ARM/Marvell Dove/Kirkwood/MV78xx0/Orion SOC support |
898 | M: Jason Cooper <jason@lakedaemon.net> | 906 | M: Jason Cooper <jason@lakedaemon.net> |
899 | M: Andrew Lunn <andrew@lunn.ch> | 907 | M: Andrew Lunn <andrew@lunn.ch> |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 02fae9adafec..7e3d9317c0bf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -533,6 +533,18 @@ config ARCH_IXP4XX | |||
533 | help | 533 | help |
534 | Support for Intel's IXP4XX (XScale) family of processors. | 534 | Support for Intel's IXP4XX (XScale) family of processors. |
535 | 535 | ||
536 | config ARCH_MVEBU | ||
537 | bool "Marvell SOCs with Device Tree support" | ||
538 | select GENERIC_CLOCKEVENTS | ||
539 | select MULTI_IRQ_HANDLER | ||
540 | select SPARSE_IRQ | ||
541 | select CLKSRC_MMIO | ||
542 | select GENERIC_IRQ_CHIP | ||
543 | select IRQ_DOMAIN | ||
544 | select COMMON_CLK | ||
545 | help | ||
546 | Support for the Marvell SoC Family with device tree support | ||
547 | |||
536 | config ARCH_DOVE | 548 | config ARCH_DOVE |
537 | bool "Marvell Dove" | 549 | bool "Marvell Dove" |
538 | select CPU_V7 | 550 | select CPU_V7 |
@@ -987,6 +999,8 @@ endchoice | |||
987 | # Kconfigs may be included either alphabetically (according to the | 999 | # Kconfigs may be included either alphabetically (according to the |
988 | # plat- suffix) or along side the corresponding mach-* source. | 1000 | # plat- suffix) or along side the corresponding mach-* source. |
989 | # | 1001 | # |
1002 | source "arch/arm/mach-mvebu/Kconfig" | ||
1003 | |||
990 | source "arch/arm/mach-at91/Kconfig" | 1004 | source "arch/arm/mach-at91/Kconfig" |
991 | 1005 | ||
992 | source "arch/arm/mach-bcmring/Kconfig" | 1006 | source "arch/arm/mach-bcmring/Kconfig" |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 0298b00fe241..f1a1a7170103 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -157,6 +157,7 @@ machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0 | |||
157 | machine-$(CONFIG_ARCH_IMX_V4_V5) := imx | 157 | machine-$(CONFIG_ARCH_IMX_V4_V5) := imx |
158 | machine-$(CONFIG_ARCH_IMX_V6_V7) := imx | 158 | machine-$(CONFIG_ARCH_IMX_V6_V7) := imx |
159 | machine-$(CONFIG_ARCH_MXS) := mxs | 159 | machine-$(CONFIG_ARCH_MXS) := mxs |
160 | machine-$(CONFIG_ARCH_MVEBU) := mvebu | ||
160 | machine-$(CONFIG_ARCH_NETX) := netx | 161 | machine-$(CONFIG_ARCH_NETX) := netx |
161 | machine-$(CONFIG_ARCH_NOMADIK) := nomadik | 162 | machine-$(CONFIG_ARCH_NOMADIK) := nomadik |
162 | machine-$(CONFIG_ARCH_OMAP1) := omap1 | 163 | machine-$(CONFIG_ARCH_OMAP1) := omap1 |
diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts new file mode 100644 index 000000000000..fffd5c2a3041 --- /dev/null +++ b/arch/arm/boot/dts/armada-370-db.dts | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * Device Tree file for Marvell Armada 370 evaluation board | ||
3 | * (DB-88F6710-BP-DDR3) | ||
4 | * | ||
5 | * Copyright (C) 2012 Marvell | ||
6 | * | ||
7 | * Lior Amsalem <alior@marvell.com> | ||
8 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
9 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
10 | * | ||
11 | * This file is licensed under the terms of the GNU General Public | ||
12 | * License version 2. This program is licensed "as is" without any | ||
13 | * warranty of any kind, whether express or implied. | ||
14 | */ | ||
15 | |||
16 | /dts-v1/; | ||
17 | /include/ "armada-370.dtsi" | ||
18 | |||
19 | / { | ||
20 | model = "Marvell Armada 370 Evaluation Board"; | ||
21 | compatible = "marvell,a370-db", "marvell,armada370", "marvell,armada-370-xp"; | ||
22 | |||
23 | chosen { | ||
24 | bootargs = "console=ttyS0,115200 earlyprintk"; | ||
25 | }; | ||
26 | |||
27 | memory { | ||
28 | device_type = "memory"; | ||
29 | reg = <0x00000000 0x20000000>; /* 512 MB */ | ||
30 | }; | ||
31 | |||
32 | soc { | ||
33 | serial@d0012000 { | ||
34 | clock-frequency = <200000000>; | ||
35 | status = "okay"; | ||
36 | }; | ||
37 | timer@d0020300 { | ||
38 | clock-frequency = <600000000>; | ||
39 | status = "okay"; | ||
40 | }; | ||
41 | }; | ||
42 | }; | ||
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi new file mode 100644 index 000000000000..6b6b932a5a7d --- /dev/null +++ b/arch/arm/boot/dts/armada-370-xp.dtsi | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * Device Tree Include file for Marvell Armada 370 and Armada XP SoC | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
8 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
9 | * Ben Dooks <ben.dooks@codethink.co.uk> | ||
10 | * | ||
11 | * This file is licensed under the terms of the GNU General Public | ||
12 | * License version 2. This program is licensed "as is" without any | ||
13 | * warranty of any kind, whether express or implied. | ||
14 | * | ||
15 | * This file contains the definitions that are common to the Armada | ||
16 | * 370 and Armada XP SoC. | ||
17 | */ | ||
18 | |||
19 | /include/ "skeleton.dtsi" | ||
20 | |||
21 | / { | ||
22 | model = "Marvell Armada 370 and XP SoC"; | ||
23 | compatible = "marvell,armada_370_xp"; | ||
24 | |||
25 | cpus { | ||
26 | cpu@0 { | ||
27 | compatible = "marvell,sheeva-v7"; | ||
28 | }; | ||
29 | }; | ||
30 | |||
31 | mpic: interrupt-controller@d0020000 { | ||
32 | compatible = "marvell,mpic"; | ||
33 | #interrupt-cells = <1>; | ||
34 | #address-cells = <1>; | ||
35 | #size-cells = <1>; | ||
36 | interrupt-controller; | ||
37 | }; | ||
38 | |||
39 | soc { | ||
40 | #address-cells = <1>; | ||
41 | #size-cells = <1>; | ||
42 | compatible = "simple-bus"; | ||
43 | interrupt-parent = <&mpic>; | ||
44 | ranges; | ||
45 | |||
46 | serial@d0012000 { | ||
47 | compatible = "ns16550"; | ||
48 | reg = <0xd0012000 0x100>; | ||
49 | reg-shift = <2>; | ||
50 | interrupts = <41>; | ||
51 | status = "disabled"; | ||
52 | }; | ||
53 | serial@d0012100 { | ||
54 | compatible = "ns16550"; | ||
55 | reg = <0xd0012100 0x100>; | ||
56 | reg-shift = <2>; | ||
57 | interrupts = <42>; | ||
58 | status = "disabled"; | ||
59 | }; | ||
60 | |||
61 | timer@d0020300 { | ||
62 | compatible = "marvell,armada-370-xp-timer"; | ||
63 | reg = <0xd0020300 0x30>; | ||
64 | interrupts = <37>, <38>, <39>, <40>; | ||
65 | }; | ||
66 | }; | ||
67 | }; | ||
68 | |||
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi new file mode 100644 index 000000000000..3228ccc83332 --- /dev/null +++ b/arch/arm/boot/dts/armada-370.dtsi | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Device Tree Include file for Marvell Armada 370 family SoC | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
8 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
9 | * | ||
10 | * This file is licensed under the terms of the GNU General Public | ||
11 | * License version 2. This program is licensed "as is" without any | ||
12 | * warranty of any kind, whether express or implied. | ||
13 | * | ||
14 | * Contains definitions specific to the Armada 370 SoC that are not | ||
15 | * common to all Armada SoCs. | ||
16 | */ | ||
17 | |||
18 | /include/ "armada-370-xp.dtsi" | ||
19 | |||
20 | / { | ||
21 | model = "Marvell Armada 370 family SoC"; | ||
22 | compatible = "marvell,armada370", "marvell,armada-370-xp"; | ||
23 | |||
24 | mpic: interrupt-controller@d0020000 { | ||
25 | reg = <0xd0020a00 0x1d0>, | ||
26 | <0xd0021870 0x58>; | ||
27 | }; | ||
28 | |||
29 | soc { | ||
30 | system-controller@d0018200 { | ||
31 | compatible = "marvell,armada-370-xp-system-controller"; | ||
32 | reg = <0xd0018200 0x100>; | ||
33 | }; | ||
34 | }; | ||
35 | }; | ||
diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts new file mode 100644 index 000000000000..f97040d4258d --- /dev/null +++ b/arch/arm/boot/dts/armada-xp-db.dts | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * Device Tree file for Marvell Armada XP evaluation board | ||
3 | * (DB-78460-BP) | ||
4 | * | ||
5 | * Copyright (C) 2012 Marvell | ||
6 | * | ||
7 | * Lior Amsalem <alior@marvell.com> | ||
8 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
9 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
10 | * | ||
11 | * This file is licensed under the terms of the GNU General Public | ||
12 | * License version 2. This program is licensed "as is" without any | ||
13 | * warranty of any kind, whether express or implied. | ||
14 | */ | ||
15 | |||
16 | /dts-v1/; | ||
17 | /include/ "armada-xp.dtsi" | ||
18 | |||
19 | / { | ||
20 | model = "Marvell Armada XP Evaluation Board"; | ||
21 | compatible = "marvell,axp-db", "marvell,armadaxp", "marvell,armada-370-xp"; | ||
22 | |||
23 | chosen { | ||
24 | bootargs = "console=ttyS0,115200 earlyprintk"; | ||
25 | }; | ||
26 | |||
27 | memory { | ||
28 | device_type = "memory"; | ||
29 | reg = <0x00000000 0x80000000>; /* 2 GB */ | ||
30 | }; | ||
31 | |||
32 | soc { | ||
33 | serial@d0012000 { | ||
34 | clock-frequency = <250000000>; | ||
35 | status = "okay"; | ||
36 | }; | ||
37 | serial@d0012100 { | ||
38 | clock-frequency = <250000000>; | ||
39 | status = "okay"; | ||
40 | }; | ||
41 | serial@d0012200 { | ||
42 | clock-frequency = <250000000>; | ||
43 | status = "okay"; | ||
44 | }; | ||
45 | serial@d0012300 { | ||
46 | clock-frequency = <250000000>; | ||
47 | status = "okay"; | ||
48 | }; | ||
49 | }; | ||
50 | }; | ||
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi new file mode 100644 index 000000000000..e1fa7e6edfe8 --- /dev/null +++ b/arch/arm/boot/dts/armada-xp.dtsi | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * Device Tree Include file for Marvell Armada XP family SoC | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
8 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
9 | * Ben Dooks <ben.dooks@codethink.co.uk> | ||
10 | * | ||
11 | * This file is licensed under the terms of the GNU General Public | ||
12 | * License version 2. This program is licensed "as is" without any | ||
13 | * warranty of any kind, whether express or implied. | ||
14 | * | ||
15 | * Contains definitions specific to the Armada 370 SoC that are not | ||
16 | * common to all Armada SoCs. | ||
17 | */ | ||
18 | |||
19 | /include/ "armada-370-xp.dtsi" | ||
20 | |||
21 | / { | ||
22 | model = "Marvell Armada XP family SoC"; | ||
23 | compatible = "marvell,armadaxp", "marvell,armada-370-xp"; | ||
24 | |||
25 | mpic: interrupt-controller@d0020000 { | ||
26 | reg = <0xd0020a00 0x1d0>, | ||
27 | <0xd0021870 0x58>; | ||
28 | }; | ||
29 | |||
30 | soc { | ||
31 | serial@d0012200 { | ||
32 | compatible = "ns16550"; | ||
33 | reg = <0xd0012200 0x100>; | ||
34 | reg-shift = <2>; | ||
35 | interrupts = <43>; | ||
36 | status = "disabled"; | ||
37 | }; | ||
38 | serial@d0012300 { | ||
39 | compatible = "ns16550"; | ||
40 | reg = <0xd0012300 0x100>; | ||
41 | reg-shift = <2>; | ||
42 | interrupts = <44>; | ||
43 | status = "disabled"; | ||
44 | }; | ||
45 | |||
46 | timer@d0020300 { | ||
47 | marvell,timer-25Mhz; | ||
48 | }; | ||
49 | |||
50 | system-controller@d0018200 { | ||
51 | compatible = "marvell,armada-370-xp-system-controller"; | ||
52 | reg = <0xd0018200 0x500>; | ||
53 | }; | ||
54 | }; | ||
55 | }; | ||
diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig new file mode 100644 index 000000000000..2e86b31c33cf --- /dev/null +++ b/arch/arm/configs/mvebu_defconfig | |||
@@ -0,0 +1,46 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | ||
2 | CONFIG_SYSVIPC=y | ||
3 | CONFIG_NO_HZ=y | ||
4 | CONFIG_HIGH_RES_TIMERS=y | ||
5 | CONFIG_LOG_BUF_SHIFT=14 | ||
6 | CONFIG_BLK_DEV_INITRD=y | ||
7 | CONFIG_EXPERT=y | ||
8 | CONFIG_SLAB=y | ||
9 | CONFIG_MODULES=y | ||
10 | CONFIG_MODULE_UNLOAD=y | ||
11 | CONFIG_ARCH_MVEBU=y | ||
12 | CONFIG_MACH_ARMADA_370_XP=y | ||
13 | CONFIG_AEABI=y | ||
14 | CONFIG_HIGHMEM=y | ||
15 | CONFIG_USE_OF=y | ||
16 | CONFIG_ZBOOT_ROM_TEXT=0x0 | ||
17 | CONFIG_ZBOOT_ROM_BSS=0x0 | ||
18 | CONFIG_ARM_APPENDED_DTB=y | ||
19 | CONFIG_VFP=y | ||
20 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
21 | CONFIG_SERIAL_8250=y | ||
22 | CONFIG_SERIAL_8250_CONSOLE=y | ||
23 | CONFIG_SERIAL_OF_PLATFORM=y | ||
24 | CONFIG_EXT2_FS=y | ||
25 | CONFIG_EXT3_FS=y | ||
26 | # CONFIG_EXT3_FS_XATTR is not set | ||
27 | CONFIG_ISO9660_FS=y | ||
28 | CONFIG_JOLIET=y | ||
29 | CONFIG_UDF_FS=m | ||
30 | CONFIG_MSDOS_FS=y | ||
31 | CONFIG_VFAT_FS=y | ||
32 | CONFIG_TMPFS=y | ||
33 | CONFIG_NLS_CODEPAGE_437=y | ||
34 | CONFIG_NLS_CODEPAGE_850=y | ||
35 | CONFIG_NLS_ISO8859_1=y | ||
36 | CONFIG_NLS_ISO8859_2=y | ||
37 | CONFIG_NLS_UTF8=y | ||
38 | CONFIG_MAGIC_SYSRQ=y | ||
39 | CONFIG_DEBUG_FS=y | ||
40 | # CONFIG_SCHED_DEBUG is not set | ||
41 | CONFIG_TIMER_STATS=y | ||
42 | # CONFIG_DEBUG_BUGVERBOSE is not set | ||
43 | CONFIG_DEBUG_INFO=y | ||
44 | CONFIG_DEBUG_USER=y | ||
45 | CONFIG_DEBUG_LL=y | ||
46 | CONFIG_EARLY_PRINTK=y | ||
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig new file mode 100644 index 000000000000..caa2c5e734fe --- /dev/null +++ b/arch/arm/mach-mvebu/Kconfig | |||
@@ -0,0 +1,16 @@ | |||
1 | if ARCH_MVEBU | ||
2 | |||
3 | menu "Marvell SOC with device tree" | ||
4 | |||
5 | config MACH_ARMADA_370_XP | ||
6 | bool "Marvell Armada 370 and Aramada XP boards" | ||
7 | select ARMADA_370_XP_TIMER | ||
8 | select CPU_V7 | ||
9 | help | ||
10 | |||
11 | Say 'Y' here if you want your kernel to support boards based on | ||
12 | Marvell Armada 370 or Armada XP with device tree. | ||
13 | |||
14 | endmenu | ||
15 | |||
16 | endif | ||
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile new file mode 100644 index 000000000000..e61d2b8fdf50 --- /dev/null +++ b/arch/arm/mach-mvebu/Makefile | |||
@@ -0,0 +1,2 @@ | |||
1 | obj-y += system-controller.o | ||
2 | obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o | ||
diff --git a/arch/arm/mach-mvebu/Makefile.boot b/arch/arm/mach-mvebu/Makefile.boot new file mode 100644 index 000000000000..b3271754e9fd --- /dev/null +++ b/arch/arm/mach-mvebu/Makefile.boot | |||
@@ -0,0 +1 @@ | |||
zreladdr-y := 0x00008000 | |||
diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c new file mode 100644 index 000000000000..4ef923b032ec --- /dev/null +++ b/arch/arm/mach-mvebu/armada-370-xp.c | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * Device Tree support for Armada 370 and XP platforms. | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
8 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
9 | * | ||
10 | * This file is licensed under the terms of the GNU General Public | ||
11 | * License version 2. This program is licensed "as is" without any | ||
12 | * warranty of any kind, whether express or implied. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/of_platform.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/time-armada-370-xp.h> | ||
20 | #include <asm/mach/arch.h> | ||
21 | #include <asm/mach/map.h> | ||
22 | #include <asm/mach/time.h> | ||
23 | #include <mach/armada-370-xp.h> | ||
24 | #include "common.h" | ||
25 | |||
26 | static struct map_desc armada_370_xp_io_desc[] __initdata = { | ||
27 | { | ||
28 | .virtual = ARMADA_370_XP_REGS_VIRT_BASE, | ||
29 | .pfn = __phys_to_pfn(ARMADA_370_XP_REGS_PHYS_BASE), | ||
30 | .length = ARMADA_370_XP_REGS_SIZE, | ||
31 | .type = MT_DEVICE, | ||
32 | }, | ||
33 | }; | ||
34 | |||
35 | void __init armada_370_xp_map_io(void) | ||
36 | { | ||
37 | iotable_init(armada_370_xp_io_desc, ARRAY_SIZE(armada_370_xp_io_desc)); | ||
38 | } | ||
39 | |||
40 | struct sys_timer armada_370_xp_timer = { | ||
41 | .init = armada_370_xp_timer_init, | ||
42 | }; | ||
43 | |||
44 | static void __init armada_370_xp_dt_init(void) | ||
45 | { | ||
46 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | ||
47 | } | ||
48 | |||
49 | static const char * const armada_370_xp_dt_board_dt_compat[] = { | ||
50 | "marvell,a370-db", | ||
51 | "marvell,axp-db", | ||
52 | NULL, | ||
53 | }; | ||
54 | |||
55 | DT_MACHINE_START(ARMADA_XP_DT, "Marvell Aramada 370/XP (Device Tree)") | ||
56 | .init_machine = armada_370_xp_dt_init, | ||
57 | .map_io = armada_370_xp_map_io, | ||
58 | .init_irq = armada_370_xp_init_irq, | ||
59 | .handle_irq = armada_370_xp_handle_irq, | ||
60 | .timer = &armada_370_xp_timer, | ||
61 | .restart = mvebu_restart, | ||
62 | .dt_compat = armada_370_xp_dt_board_dt_compat, | ||
63 | MACHINE_END | ||
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h new file mode 100644 index 000000000000..02f89eaa25fe --- /dev/null +++ b/arch/arm/mach-mvebu/common.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * Core functions for Marvell System On Chip | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
8 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
9 | * | ||
10 | * This file is licensed under the terms of the GNU General Public | ||
11 | * License version 2. This program is licensed "as is" without any | ||
12 | * warranty of any kind, whether express or implied. | ||
13 | */ | ||
14 | |||
15 | #ifndef __ARCH_MVEBU_COMMON_H | ||
16 | #define __ARCH_MVEBU_COMMON_H | ||
17 | |||
18 | void mvebu_restart(char mode, const char *cmd); | ||
19 | |||
20 | void armada_370_xp_init_irq(void); | ||
21 | void armada_370_xp_handle_irq(struct pt_regs *regs); | ||
22 | |||
23 | #endif | ||
diff --git a/arch/arm/mach-mvebu/include/mach/armada-370-xp.h b/arch/arm/mach-mvebu/include/mach/armada-370-xp.h new file mode 100644 index 000000000000..25f0ca8d7820 --- /dev/null +++ b/arch/arm/mach-mvebu/include/mach/armada-370-xp.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Generic definitions for Marvell Armada_370_XP SoCs | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
8 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
9 | * | ||
10 | * This file is licensed under the terms of the GNU General Public | ||
11 | * License version 2. This program is licensed "as is" without any | ||
12 | * warranty of any kind, whether express or implied. | ||
13 | */ | ||
14 | |||
15 | #ifndef __MACH_ARMADA_370_XP_H | ||
16 | #define __MACH_ARMADA_370_XP_H | ||
17 | |||
18 | #define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000 | ||
19 | #define ARMADA_370_XP_REGS_VIRT_BASE 0xfeb00000 | ||
20 | #define ARMADA_370_XP_REGS_SIZE SZ_1M | ||
21 | |||
22 | #endif /* __MACH_ARMADA_370_XP_H */ | ||
diff --git a/arch/arm/mach-mvebu/include/mach/debug-macro.S b/arch/arm/mach-mvebu/include/mach/debug-macro.S new file mode 100644 index 000000000000..22825760c7e1 --- /dev/null +++ b/arch/arm/mach-mvebu/include/mach/debug-macro.S | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Early serial output macro for Marvell SoC | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * Gregory Clement <gregory.clement@free-electrons.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <mach/armada-370-xp.h> | ||
15 | |||
16 | .macro addruart, rp, rv, tmp | ||
17 | ldr \rp, =ARMADA_370_XP_REGS_PHYS_BASE | ||
18 | ldr \rv, =ARMADA_370_XP_REGS_VIRT_BASE | ||
19 | orr \rp, \rp, #0x00012000 | ||
20 | orr \rv, \rv, #0x00012000 | ||
21 | .endm | ||
22 | |||
23 | #define UART_SHIFT 2 | ||
24 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-mvebu/include/mach/timex.h b/arch/arm/mach-mvebu/include/mach/timex.h new file mode 100644 index 000000000000..ab324a3748f2 --- /dev/null +++ b/arch/arm/mach-mvebu/include/mach/timex.h | |||
@@ -0,0 +1,13 @@ | |||
1 | /* | ||
2 | * Marvell Armada SoC time definitions | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #define CLOCK_TICK_RATE (100 * HZ) | ||
diff --git a/arch/arm/mach-mvebu/include/mach/uncompress.h b/arch/arm/mach-mvebu/include/mach/uncompress.h new file mode 100644 index 000000000000..d6a100ccf302 --- /dev/null +++ b/arch/arm/mach-mvebu/include/mach/uncompress.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * Marvell Armada SoC kernel uncompression UART routines | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <mach/armada-370-xp.h> | ||
14 | |||
15 | #define UART_THR ((volatile unsigned char *)(ARMADA_370_XP_REGS_PHYS_BASE\ | ||
16 | + 0x12000)) | ||
17 | #define UART_LSR ((volatile unsigned char *)(ARMADA_370_XP_REGS_PHYS_BASE\ | ||
18 | + 0x12014)) | ||
19 | |||
20 | #define LSR_THRE 0x20 | ||
21 | |||
22 | static void putc(const char c) | ||
23 | { | ||
24 | int i; | ||
25 | |||
26 | for (i = 0; i < 0x1000; i++) { | ||
27 | /* Transmit fifo not full? */ | ||
28 | if (*UART_LSR & LSR_THRE) | ||
29 | break; | ||
30 | } | ||
31 | |||
32 | *UART_THR = c; | ||
33 | } | ||
34 | |||
35 | static void flush(void) | ||
36 | { | ||
37 | } | ||
38 | |||
39 | /* | ||
40 | * nothing to do | ||
41 | */ | ||
42 | #define arch_decomp_setup() | ||
43 | #define arch_decomp_wdog() | ||
diff --git a/arch/arm/mach-mvebu/irq-armada-370-xp.c b/arch/arm/mach-mvebu/irq-armada-370-xp.c new file mode 100644 index 000000000000..5f5f9394b6b2 --- /dev/null +++ b/arch/arm/mach-mvebu/irq-armada-370-xp.c | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * Marvell Armada 370 and Armada XP SoC IRQ handling | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
8 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
9 | * Ben Dooks <ben.dooks@codethink.co.uk> | ||
10 | * | ||
11 | * This file is licensed under the terms of the GNU General Public | ||
12 | * License version 2. This program is licensed "as is" without any | ||
13 | * warranty of any kind, whether express or implied. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/irq.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/of_address.h> | ||
23 | #include <linux/of_irq.h> | ||
24 | #include <linux/irqdomain.h> | ||
25 | #include <asm/mach/arch.h> | ||
26 | #include <asm/exception.h> | ||
27 | |||
28 | /* Interrupt Controller Registers Map */ | ||
29 | #define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48) | ||
30 | #define ARMADA_370_XP_INT_CLEAR_MASK_OFFS (0x4C) | ||
31 | |||
32 | #define ARMADA_370_XP_INT_CONTROL (0x00) | ||
33 | #define ARMADA_370_XP_INT_SET_ENABLE_OFFS (0x30) | ||
34 | #define ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS (0x34) | ||
35 | |||
36 | #define ARMADA_370_XP_CPU_INTACK_OFFS (0x44) | ||
37 | |||
38 | static void __iomem *per_cpu_int_base; | ||
39 | static void __iomem *main_int_base; | ||
40 | static struct irq_domain *armada_370_xp_mpic_domain; | ||
41 | |||
42 | static void armada_370_xp_irq_mask(struct irq_data *d) | ||
43 | { | ||
44 | writel(irqd_to_hwirq(d), | ||
45 | per_cpu_int_base + ARMADA_370_XP_INT_SET_MASK_OFFS); | ||
46 | } | ||
47 | |||
48 | static void armada_370_xp_irq_unmask(struct irq_data *d) | ||
49 | { | ||
50 | writel(irqd_to_hwirq(d), | ||
51 | per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); | ||
52 | } | ||
53 | |||
54 | static struct irq_chip armada_370_xp_irq_chip = { | ||
55 | .name = "armada_370_xp_irq", | ||
56 | .irq_mask = armada_370_xp_irq_mask, | ||
57 | .irq_mask_ack = armada_370_xp_irq_mask, | ||
58 | .irq_unmask = armada_370_xp_irq_unmask, | ||
59 | }; | ||
60 | |||
61 | static int armada_370_xp_mpic_irq_map(struct irq_domain *h, | ||
62 | unsigned int virq, irq_hw_number_t hw) | ||
63 | { | ||
64 | armada_370_xp_irq_mask(irq_get_irq_data(virq)); | ||
65 | writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); | ||
66 | |||
67 | irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip, | ||
68 | handle_level_irq); | ||
69 | irq_set_status_flags(virq, IRQ_LEVEL); | ||
70 | set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { | ||
76 | .map = armada_370_xp_mpic_irq_map, | ||
77 | .xlate = irq_domain_xlate_onecell, | ||
78 | }; | ||
79 | |||
80 | static int __init armada_370_xp_mpic_of_init(struct device_node *node, | ||
81 | struct device_node *parent) | ||
82 | { | ||
83 | u32 control; | ||
84 | |||
85 | main_int_base = of_iomap(node, 0); | ||
86 | per_cpu_int_base = of_iomap(node, 1); | ||
87 | |||
88 | BUG_ON(!main_int_base); | ||
89 | BUG_ON(!per_cpu_int_base); | ||
90 | |||
91 | control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL); | ||
92 | |||
93 | armada_370_xp_mpic_domain = | ||
94 | irq_domain_add_linear(node, (control >> 2) & 0x3ff, | ||
95 | &armada_370_xp_mpic_irq_ops, NULL); | ||
96 | |||
97 | if (!armada_370_xp_mpic_domain) | ||
98 | panic("Unable to add Armada_370_Xp MPIC irq domain (DT)\n"); | ||
99 | |||
100 | irq_set_default_host(armada_370_xp_mpic_domain); | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | asmlinkage void __exception_irq_entry armada_370_xp_handle_irq(struct pt_regs | ||
105 | *regs) | ||
106 | { | ||
107 | u32 irqstat, irqnr; | ||
108 | |||
109 | do { | ||
110 | irqstat = readl_relaxed(per_cpu_int_base + | ||
111 | ARMADA_370_XP_CPU_INTACK_OFFS); | ||
112 | irqnr = irqstat & 0x3FF; | ||
113 | |||
114 | if (irqnr < 1023) { | ||
115 | irqnr = | ||
116 | irq_find_mapping(armada_370_xp_mpic_domain, irqnr); | ||
117 | handle_IRQ(irqnr, regs); | ||
118 | continue; | ||
119 | } | ||
120 | |||
121 | break; | ||
122 | } while (1); | ||
123 | } | ||
124 | |||
125 | static const struct of_device_id mpic_of_match[] __initconst = { | ||
126 | {.compatible = "marvell,mpic", .data = armada_370_xp_mpic_of_init}, | ||
127 | {}, | ||
128 | }; | ||
129 | |||
130 | void __init armada_370_xp_init_irq(void) | ||
131 | { | ||
132 | of_irq_init(mpic_of_match); | ||
133 | } | ||
diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c new file mode 100644 index 000000000000..b8079df8c986 --- /dev/null +++ b/arch/arm/mach-mvebu/system-controller.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * System controller support for Armada 370 and XP platforms. | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
8 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
9 | * | ||
10 | * This file is licensed under the terms of the GNU General Public | ||
11 | * License version 2. This program is licensed "as is" without any | ||
12 | * warranty of any kind, whether express or implied. | ||
13 | * | ||
14 | * The Armada 370 and Armada XP SoCs both have a range of | ||
15 | * miscellaneous registers, that do not belong to a particular device, | ||
16 | * but rather provide system-level features. This basic | ||
17 | * system-controller driver provides a device tree binding for those | ||
18 | * registers, and implements utility functions offering various | ||
19 | * features related to those registers. | ||
20 | * | ||
21 | * For now, the feature set is limited to restarting the platform by a | ||
22 | * soft-reset, but it might be extended in the future. | ||
23 | */ | ||
24 | |||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/of_address.h> | ||
28 | #include <linux/io.h> | ||
29 | |||
30 | static void __iomem *system_controller_base; | ||
31 | |||
32 | struct mvebu_system_controller { | ||
33 | u32 rstoutn_mask_offset; | ||
34 | u32 system_soft_reset_offset; | ||
35 | |||
36 | u32 rstoutn_mask_reset_out_en; | ||
37 | u32 system_soft_reset; | ||
38 | }; | ||
39 | static struct mvebu_system_controller *mvebu_sc; | ||
40 | |||
41 | const struct mvebu_system_controller armada_370_xp_system_controller = { | ||
42 | .rstoutn_mask_offset = 0x60, | ||
43 | .system_soft_reset_offset = 0x64, | ||
44 | .rstoutn_mask_reset_out_en = 0x1, | ||
45 | .system_soft_reset = 0x1, | ||
46 | }; | ||
47 | |||
48 | const struct mvebu_system_controller orion_system_controller = { | ||
49 | .rstoutn_mask_offset = 0x108, | ||
50 | .system_soft_reset_offset = 0x10c, | ||
51 | .rstoutn_mask_reset_out_en = 0x4, | ||
52 | .system_soft_reset = 0x1, | ||
53 | }; | ||
54 | |||
55 | static struct of_device_id of_system_controller_table[] = { | ||
56 | { | ||
57 | .compatible = "marvell,orion-system-controller", | ||
58 | .data = (void *) &orion_system_controller, | ||
59 | }, { | ||
60 | .compatible = "marvell,armada-370-xp-system-controller", | ||
61 | .data = (void *) &armada_370_xp_system_controller, | ||
62 | }, | ||
63 | { /* end of list */ }, | ||
64 | }; | ||
65 | |||
66 | void mvebu_restart(char mode, const char *cmd) | ||
67 | { | ||
68 | if (!system_controller_base) { | ||
69 | pr_err("Cannot restart, system-controller not available: check the device tree\n"); | ||
70 | } else { | ||
71 | /* | ||
72 | * Enable soft reset to assert RSTOUTn. | ||
73 | */ | ||
74 | writel(mvebu_sc->rstoutn_mask_reset_out_en, | ||
75 | system_controller_base + | ||
76 | mvebu_sc->rstoutn_mask_offset); | ||
77 | /* | ||
78 | * Assert soft reset. | ||
79 | */ | ||
80 | writel(mvebu_sc->system_soft_reset, | ||
81 | system_controller_base + | ||
82 | mvebu_sc->system_soft_reset_offset); | ||
83 | } | ||
84 | |||
85 | while (1) | ||
86 | ; | ||
87 | } | ||
88 | |||
89 | static int __init mvebu_system_controller_init(void) | ||
90 | { | ||
91 | struct device_node *np; | ||
92 | |||
93 | np = of_find_matching_node(NULL, of_system_controller_table); | ||
94 | if (np) { | ||
95 | const struct of_device_id *match = | ||
96 | of_match_node(of_system_controller_table, np); | ||
97 | BUG_ON(!match); | ||
98 | system_controller_base = of_iomap(np, 0); | ||
99 | mvebu_sc = (struct mvebu_system_controller *)match->data; | ||
100 | } | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | arch_initcall(mvebu_system_controller_init); | ||
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 99c6b203e6cd..b32363173584 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
@@ -16,6 +16,9 @@ config CLKSRC_MMIO | |||
16 | config DW_APB_TIMER | 16 | config DW_APB_TIMER |
17 | bool | 17 | bool |
18 | 18 | ||
19 | config ARMADA_370_XP_TIMER | ||
20 | bool | ||
21 | |||
19 | config CLKSRC_DBX500_PRCMU | 22 | config CLKSRC_DBX500_PRCMU |
20 | bool "Clocksource PRCMU Timer" | 23 | bool "Clocksource PRCMU Timer" |
21 | depends on UX500_SOC_DB8500 | 24 | depends on UX500_SOC_DB8500 |
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index dd3e661a124d..022015cbee48 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
@@ -10,4 +10,5 @@ obj-$(CONFIG_EM_TIMER_STI) += em_sti.o | |||
10 | obj-$(CONFIG_CLKBLD_I8253) += i8253.o | 10 | obj-$(CONFIG_CLKBLD_I8253) += i8253.o |
11 | obj-$(CONFIG_CLKSRC_MMIO) += mmio.o | 11 | obj-$(CONFIG_CLKSRC_MMIO) += mmio.o |
12 | obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o | 12 | obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o |
13 | obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o \ No newline at end of file | 13 | obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o |
14 | obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o | ||
diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c new file mode 100644 index 000000000000..4674f94957cd --- /dev/null +++ b/drivers/clocksource/time-armada-370-xp.c | |||
@@ -0,0 +1,226 @@ | |||
1 | /* | ||
2 | * Marvell Armada 370/XP SoC timer handling. | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
8 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
9 | * | ||
10 | * This file is licensed under the terms of the GNU General Public | ||
11 | * License version 2. This program is licensed "as is" without any | ||
12 | * warranty of any kind, whether express or implied. | ||
13 | * | ||
14 | * Timer 0 is used as free-running clocksource, while timer 1 is | ||
15 | * used as clock_event_device. | ||
16 | */ | ||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/timer.h> | ||
22 | #include <linux/clockchips.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/of.h> | ||
25 | #include <linux/of_irq.h> | ||
26 | #include <linux/of_address.h> | ||
27 | #include <linux/irq.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <asm/sched_clock.h> | ||
30 | |||
31 | /* | ||
32 | * Timer block registers. | ||
33 | */ | ||
34 | #define TIMER_CTRL_OFF 0x0000 | ||
35 | #define TIMER0_EN 0x0001 | ||
36 | #define TIMER0_RELOAD_EN 0x0002 | ||
37 | #define TIMER0_25MHZ 0x0800 | ||
38 | #define TIMER0_DIV(div) ((div) << 19) | ||
39 | #define TIMER1_EN 0x0004 | ||
40 | #define TIMER1_RELOAD_EN 0x0008 | ||
41 | #define TIMER1_25MHZ 0x1000 | ||
42 | #define TIMER1_DIV(div) ((div) << 22) | ||
43 | #define TIMER_EVENTS_STATUS 0x0004 | ||
44 | #define TIMER0_CLR_MASK (~0x1) | ||
45 | #define TIMER1_CLR_MASK (~0x100) | ||
46 | #define TIMER0_RELOAD_OFF 0x0010 | ||
47 | #define TIMER0_VAL_OFF 0x0014 | ||
48 | #define TIMER1_RELOAD_OFF 0x0018 | ||
49 | #define TIMER1_VAL_OFF 0x001c | ||
50 | |||
51 | /* Global timers are connected to the coherency fabric clock, and the | ||
52 | below divider reduces their incrementing frequency. */ | ||
53 | #define TIMER_DIVIDER_SHIFT 5 | ||
54 | #define TIMER_DIVIDER (1 << TIMER_DIVIDER_SHIFT) | ||
55 | |||
56 | /* | ||
57 | * SoC-specific data. | ||
58 | */ | ||
59 | static void __iomem *timer_base; | ||
60 | static int timer_irq; | ||
61 | |||
62 | /* | ||
63 | * Number of timer ticks per jiffy. | ||
64 | */ | ||
65 | static u32 ticks_per_jiffy; | ||
66 | |||
67 | static u32 notrace armada_370_xp_read_sched_clock(void) | ||
68 | { | ||
69 | return ~readl(timer_base + TIMER0_VAL_OFF); | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * Clockevent handling. | ||
74 | */ | ||
75 | static int | ||
76 | armada_370_xp_clkevt_next_event(unsigned long delta, | ||
77 | struct clock_event_device *dev) | ||
78 | { | ||
79 | u32 u; | ||
80 | |||
81 | /* | ||
82 | * Clear clockevent timer interrupt. | ||
83 | */ | ||
84 | writel(TIMER1_CLR_MASK, timer_base + TIMER_EVENTS_STATUS); | ||
85 | |||
86 | /* | ||
87 | * Setup new clockevent timer value. | ||
88 | */ | ||
89 | writel(delta, timer_base + TIMER1_VAL_OFF); | ||
90 | |||
91 | /* | ||
92 | * Enable the timer. | ||
93 | */ | ||
94 | u = readl(timer_base + TIMER_CTRL_OFF); | ||
95 | u = ((u & ~TIMER1_RELOAD_EN) | TIMER1_EN | | ||
96 | TIMER1_DIV(TIMER_DIVIDER_SHIFT)); | ||
97 | writel(u, timer_base + TIMER_CTRL_OFF); | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static void | ||
103 | armada_370_xp_clkevt_mode(enum clock_event_mode mode, | ||
104 | struct clock_event_device *dev) | ||
105 | { | ||
106 | u32 u; | ||
107 | |||
108 | if (mode == CLOCK_EVT_MODE_PERIODIC) { | ||
109 | /* | ||
110 | * Setup timer to fire at 1/HZ intervals. | ||
111 | */ | ||
112 | writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD_OFF); | ||
113 | writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL_OFF); | ||
114 | |||
115 | /* | ||
116 | * Enable timer. | ||
117 | */ | ||
118 | u = readl(timer_base + TIMER_CTRL_OFF); | ||
119 | |||
120 | writel((u | TIMER1_EN | TIMER1_RELOAD_EN | | ||
121 | TIMER1_DIV(TIMER_DIVIDER_SHIFT)), | ||
122 | timer_base + TIMER_CTRL_OFF); | ||
123 | } else { | ||
124 | /* | ||
125 | * Disable timer. | ||
126 | */ | ||
127 | u = readl(timer_base + TIMER_CTRL_OFF); | ||
128 | writel(u & ~TIMER1_EN, timer_base + TIMER_CTRL_OFF); | ||
129 | |||
130 | /* | ||
131 | * ACK pending timer interrupt. | ||
132 | */ | ||
133 | writel(TIMER1_CLR_MASK, timer_base + TIMER_EVENTS_STATUS); | ||
134 | |||
135 | } | ||
136 | } | ||
137 | |||
138 | static struct clock_event_device armada_370_xp_clkevt = { | ||
139 | .name = "armada_370_xp_tick", | ||
140 | .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, | ||
141 | .shift = 32, | ||
142 | .rating = 300, | ||
143 | .set_next_event = armada_370_xp_clkevt_next_event, | ||
144 | .set_mode = armada_370_xp_clkevt_mode, | ||
145 | }; | ||
146 | |||
147 | static irqreturn_t armada_370_xp_timer_interrupt(int irq, void *dev_id) | ||
148 | { | ||
149 | /* | ||
150 | * ACK timer interrupt and call event handler. | ||
151 | */ | ||
152 | |||
153 | writel(TIMER1_CLR_MASK, timer_base + TIMER_EVENTS_STATUS); | ||
154 | armada_370_xp_clkevt.event_handler(&armada_370_xp_clkevt); | ||
155 | |||
156 | return IRQ_HANDLED; | ||
157 | } | ||
158 | |||
159 | static struct irqaction armada_370_xp_timer_irq = { | ||
160 | .name = "armada_370_xp_tick", | ||
161 | .flags = IRQF_DISABLED | IRQF_TIMER, | ||
162 | .handler = armada_370_xp_timer_interrupt | ||
163 | }; | ||
164 | |||
165 | void __init armada_370_xp_timer_init(void) | ||
166 | { | ||
167 | u32 u; | ||
168 | struct device_node *np; | ||
169 | unsigned int timer_clk; | ||
170 | int ret; | ||
171 | np = of_find_compatible_node(NULL, NULL, "marvell,armada-370-xp-timer"); | ||
172 | timer_base = of_iomap(np, 0); | ||
173 | WARN_ON(!timer_base); | ||
174 | |||
175 | if (of_find_property(np, "marvell,timer-25Mhz", NULL)) { | ||
176 | /* The fixed 25MHz timer is available so let's use it */ | ||
177 | u = readl(timer_base + TIMER_CTRL_OFF); | ||
178 | writel(u | TIMER0_25MHZ | TIMER1_25MHZ, | ||
179 | timer_base + TIMER_CTRL_OFF); | ||
180 | timer_clk = 25000000; | ||
181 | } else { | ||
182 | u32 clk = 0; | ||
183 | ret = of_property_read_u32(np, "clock-frequency", &clk); | ||
184 | WARN_ON(!clk || ret < 0); | ||
185 | u = readl(timer_base + TIMER_CTRL_OFF); | ||
186 | writel(u & ~(TIMER0_25MHZ | TIMER1_25MHZ), | ||
187 | timer_base + TIMER_CTRL_OFF); | ||
188 | timer_clk = clk / TIMER_DIVIDER; | ||
189 | } | ||
190 | |||
191 | /* We use timer 0 as clocksource, and timer 1 for | ||
192 | clockevents */ | ||
193 | timer_irq = irq_of_parse_and_map(np, 1); | ||
194 | |||
195 | ticks_per_jiffy = (timer_clk + HZ / 2) / HZ; | ||
196 | |||
197 | /* | ||
198 | * Set scale and timer for sched_clock. | ||
199 | */ | ||
200 | setup_sched_clock(armada_370_xp_read_sched_clock, 32, timer_clk); | ||
201 | |||
202 | /* | ||
203 | * Setup free-running clocksource timer (interrupts | ||
204 | * disabled). | ||
205 | */ | ||
206 | writel(0xffffffff, timer_base + TIMER0_VAL_OFF); | ||
207 | writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); | ||
208 | |||
209 | u = readl(timer_base + TIMER_CTRL_OFF); | ||
210 | |||
211 | writel((u | TIMER0_EN | TIMER0_RELOAD_EN | | ||
212 | TIMER0_DIV(TIMER_DIVIDER_SHIFT)), timer_base + TIMER_CTRL_OFF); | ||
213 | |||
214 | clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, | ||
215 | "armada_370_xp_clocksource", | ||
216 | timer_clk, 300, 32, clocksource_mmio_readl_down); | ||
217 | |||
218 | /* | ||
219 | * Setup clockevent timer (interrupt-driven). | ||
220 | */ | ||
221 | setup_irq(timer_irq, &armada_370_xp_timer_irq); | ||
222 | armada_370_xp_clkevt.cpumask = cpumask_of(0); | ||
223 | clockevents_config_and_register(&armada_370_xp_clkevt, | ||
224 | timer_clk, 1, 0xfffffffe); | ||
225 | } | ||
226 | |||
diff --git a/include/linux/time-armada-370-xp.h b/include/linux/time-armada-370-xp.h new file mode 100644 index 000000000000..dfdfdc03115b --- /dev/null +++ b/include/linux/time-armada-370-xp.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * Marvell Armada 370/XP SoC timer handling. | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
8 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
9 | * | ||
10 | */ | ||
11 | #ifndef __TIME_ARMADA_370_XPPRCMU_H | ||
12 | #define __TIME_ARMADA_370_XPPRCMU_H | ||
13 | |||
14 | #include <linux/init.h> | ||
15 | |||
16 | void __init armada_370_xp_timer_init(void); | ||
17 | |||
18 | #endif | ||