aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-14 17:54:26 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-14 17:54:26 -0500
commitc2714334b944abbeaaadda8cddde619eff0292a1 (patch)
treeb45be97a313f58aa62933040230d51aa3a8592b4 /arch/arm
parent0beb58783f2168354e2b5297af45fc7db70adf12 (diff)
parent5e5d8999a316d596f2012fe1cf4c59e0de693dab (diff)
Merge tag 'mvebu' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC updates for Marvell mvebu/kirkwood from Olof Johansson: "This is a branch with updates for Marvell's mvebu/kirkwood platforms. They came in late-ish, and were heavily interdependent such that it didn't make sense to split them up across the cross-platform topic branches. So here they are (for the second release in a row) in a branch on their own." * tag 'mvebu' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (88 commits) arm: l2x0: add aurora related properties to OF binding arm: mvebu: add Aurora L2 Cache Controller to the DT arm: mvebu: add L2 cache support dma: mv_xor: fix error handling path dma: mv_xor: fix error checking of irq_of_parse_and_map() dma: mv_xor: use request_irq() instead of devm_request_irq() dma: mv_xor: clear the window override control registers arm: mvebu: fix address decoding armada_cfg_base() function ARM: mvebu: update defconfig with I2C and RTC support ARM: mvebu: Add SATA support for OpenBlocks AX3-4 ARM: mvebu: Add support for the RTC in OpenBlocks AX3-4 ARM: mvebu: Add support for I2C on OpenBlocks AX3-4 ARM: mvebu: Add support for I2C controllers in Armada 370/XP arm: mvebu: Add hardware I/O Coherency support arm: plat-orion: Add coherency attribute when setup mbus target arm: dma mapping: Export a dma ops function arm_dma_set_mask arm: mvebu: Add SMP support for Armada XP arm: mm: Add support for PJ4B cpu and init routines arm: mvebu: Add IPI support via doorbells arm: mvebu: Add initial support for power managmement service unit ...
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/boot/dts/Makefile4
-rw-r--r--arch/arm/boot/dts/armada-370-db.dts25
-rw-r--r--arch/arm/boot/dts/armada-370-mirabox.dts56
-rw-r--r--arch/arm/boot/dts/armada-370-xp.dtsi63
-rw-r--r--arch/arm/boot/dts/armada-370.dtsi57
-rw-r--r--arch/arm/boot/dts/armada-xp-db.dts44
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78230.dtsi12
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78260.dtsi19
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78460.dtsi34
-rw-r--r--arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts125
-rw-r--r--arch/arm/boot/dts/armada-xp.dtsi91
-rw-r--r--arch/arm/boot/dts/dove.dtsi62
-rw-r--r--arch/arm/boot/dts/kirkwood.dtsi62
-rw-r--r--arch/arm/configs/multi_v7_defconfig2
-rw-r--r--arch/arm/configs/mvebu_defconfig17
-rw-r--r--arch/arm/include/asm/dma-mapping.h2
-rw-r--r--arch/arm/mach-dove/Kconfig2
-rw-r--r--arch/arm/mach-dove/common.c62
-rw-r--r--arch/arm/mach-kirkwood/Kconfig2
-rw-r--r--arch/arm/mach-kirkwood/board-dt.c69
-rw-r--r--arch/arm/mach-kirkwood/common.c4
-rw-r--r--arch/arm/mach-mvebu/Kconfig8
-rw-r--r--arch/arm/mach-mvebu/Makefile4
-rw-r--r--arch/arm/mach-mvebu/addr-map.c5
-rw-r--r--arch/arm/mach-mvebu/armada-370-xp.c33
-rw-r--r--arch/arm/mach-mvebu/armada-370-xp.h7
-rw-r--r--arch/arm/mach-mvebu/coherency.c155
-rw-r--r--arch/arm/mach-mvebu/coherency.h24
-rw-r--r--arch/arm/mach-mvebu/coherency_ll.S49
-rw-r--r--arch/arm/mach-mvebu/common.h5
-rw-r--r--arch/arm/mach-mvebu/headsmp.S49
-rw-r--r--arch/arm/mach-mvebu/hotplug.c30
-rw-r--r--arch/arm/mach-mvebu/irq-armada-370-xp.c96
-rw-r--r--arch/arm/mach-mvebu/platsmp.c122
-rw-r--r--arch/arm/mach-mvebu/pmsu.c75
-rw-r--r--arch/arm/mach-mvebu/pmsu.h16
-rw-r--r--arch/arm/mm/Kconfig4
-rw-r--r--arch/arm/mm/dma-mapping.c4
-rw-r--r--arch/arm/mm/proc-v7.S67
-rw-r--r--arch/arm/plat-orion/addr-map.c4
-rw-r--r--arch/arm/plat-orion/common.c192
-rw-r--r--arch/arm/plat-orion/include/plat/addr-map.h1
-rw-r--r--arch/arm/plat-orion/include/plat/common.h1
44 files changed, 1574 insertions, 192 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2277f9530b00..8c83d98424c7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -533,6 +533,7 @@ config ARCH_IXP4XX
533config ARCH_DOVE 533config ARCH_DOVE
534 bool "Marvell Dove" 534 bool "Marvell Dove"
535 select ARCH_REQUIRE_GPIOLIB 535 select ARCH_REQUIRE_GPIOLIB
536 select COMMON_CLK_DOVE
536 select CPU_V7 537 select CPU_V7
537 select GENERIC_CLOCKEVENTS 538 select GENERIC_CLOCKEVENTS
538 select MIGHT_HAVE_PCI 539 select MIGHT_HAVE_PCI
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index d0ae1d3a90d9..0f441740c22a 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -77,7 +77,9 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-dns320.dtb \
77dtb-$(CONFIG_ARCH_MSM) += msm8660-surf.dtb \ 77dtb-$(CONFIG_ARCH_MSM) += msm8660-surf.dtb \
78 msm8960-cdp.dtb 78 msm8960-cdp.dtb
79dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ 79dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
80 armada-xp-db.dtb 80 armada-370-mirabox.dtb \
81 armada-xp-db.dtb \
82 armada-xp-openblocks-ax3-4.dtb
81dtb-$(CONFIG_ARCH_MXC) += imx51-babbage.dtb \ 83dtb-$(CONFIG_ARCH_MXC) += imx51-babbage.dtb \
82 imx53-ard.dtb \ 84 imx53-ard.dtb \
83 imx53-evk.dtb \ 85 imx53-evk.dtb \
diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts
index fffd5c2a3041..00044026ef1f 100644
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -34,9 +34,30 @@
34 clock-frequency = <200000000>; 34 clock-frequency = <200000000>;
35 status = "okay"; 35 status = "okay";
36 }; 36 };
37 timer@d0020300 { 37 sata@d00a0000 {
38 clock-frequency = <600000000>; 38 nr-ports = <2>;
39 status = "okay"; 39 status = "okay";
40 }; 40 };
41
42 mdio {
43 phy0: ethernet-phy@0 {
44 reg = <0>;
45 };
46
47 phy1: ethernet-phy@1 {
48 reg = <1>;
49 };
50 };
51
52 ethernet@d0070000 {
53 status = "okay";
54 phy = <&phy0>;
55 phy-mode = "rgmii-id";
56 };
57 ethernet@d0074000 {
58 status = "okay";
59 phy = <&phy1>;
60 phy-mode = "rgmii-id";
61 };
41 }; 62 };
42}; 63};
diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts
new file mode 100644
index 000000000000..3b4071336599
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-mirabox.dts
@@ -0,0 +1,56 @@
1/*
2 * Device Tree file for Globalscale Mirabox
3 *
4 * Gregory CLEMENT <gregory.clement@free-electrons.com>
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/dts-v1/;
12/include/ "armada-370.dtsi"
13
14/ {
15 model = "Globalscale Mirabox";
16 compatible = "globalscale,mirabox", "marvell,armada370", "marvell,armada-370-xp";
17
18 chosen {
19 bootargs = "console=ttyS0,115200 earlyprintk";
20 };
21
22 memory {
23 device_type = "memory";
24 reg = <0x00000000 0x20000000>; /* 512 MB */
25 };
26
27 soc {
28 serial@d0012000 {
29 clock-frequency = <200000000>;
30 status = "okay";
31 };
32 timer@d0020300 {
33 clock-frequency = <600000000>;
34 status = "okay";
35 };
36 mdio {
37 phy0: ethernet-phy@0 {
38 reg = <0>;
39 };
40
41 phy1: ethernet-phy@1 {
42 reg = <1>;
43 };
44 };
45 ethernet@d0070000 {
46 status = "okay";
47 phy = <&phy0>;
48 phy-mode = "rgmii-id";
49 };
50 ethernet@d0074000 {
51 status = "okay";
52 phy = <&phy1>;
53 phy-mode = "rgmii-id";
54 };
55 };
56};
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 16cc82cdaa81..cf6c48a09eac 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -20,7 +20,7 @@
20 20
21/ { 21/ {
22 model = "Marvell Armada 370 and XP SoC"; 22 model = "Marvell Armada 370 and XP SoC";
23 compatible = "marvell,armada_370_xp"; 23 compatible = "marvell,armada-370-xp";
24 24
25 cpus { 25 cpus {
26 cpu@0 { 26 cpu@0 {
@@ -36,6 +36,12 @@
36 interrupt-controller; 36 interrupt-controller;
37 }; 37 };
38 38
39 coherency-fabric@d0020200 {
40 compatible = "marvell,coherency-fabric";
41 reg = <0xd0020200 0xb0>,
42 <0xd0021810 0x1c>;
43 };
44
39 soc { 45 soc {
40 #address-cells = <1>; 46 #address-cells = <1>;
41 #size-cells = <1>; 47 #size-cells = <1>;
@@ -62,12 +68,67 @@
62 compatible = "marvell,armada-370-xp-timer"; 68 compatible = "marvell,armada-370-xp-timer";
63 reg = <0xd0020300 0x30>; 69 reg = <0xd0020300 0x30>;
64 interrupts = <37>, <38>, <39>, <40>; 70 interrupts = <37>, <38>, <39>, <40>;
71 clocks = <&coreclk 2>;
65 }; 72 };
66 73
67 addr-decoding@d0020000 { 74 addr-decoding@d0020000 {
68 compatible = "marvell,armada-addr-decoding-controller"; 75 compatible = "marvell,armada-addr-decoding-controller";
69 reg = <0xd0020000 0x258>; 76 reg = <0xd0020000 0x258>;
70 }; 77 };
78
79 sata@d00a0000 {
80 compatible = "marvell,orion-sata";
81 reg = <0xd00a0000 0x2400>;
82 interrupts = <55>;
83 clocks = <&gateclk 15>, <&gateclk 30>;
84 clock-names = "0", "1";
85 status = "disabled";
86 };
87
88 mdio {
89 #address-cells = <1>;
90 #size-cells = <0>;
91 compatible = "marvell,orion-mdio";
92 reg = <0xd0072004 0x4>;
93 };
94
95 ethernet@d0070000 {
96 compatible = "marvell,armada-370-neta";
97 reg = <0xd0070000 0x2500>;
98 interrupts = <8>;
99 clocks = <&gateclk 4>;
100 status = "disabled";
101 };
102
103 ethernet@d0074000 {
104 compatible = "marvell,armada-370-neta";
105 reg = <0xd0074000 0x2500>;
106 interrupts = <10>;
107 clocks = <&gateclk 3>;
108 status = "disabled";
109 };
110
111 i2c0: i2c@d0011000 {
112 compatible = "marvell,mv64xxx-i2c";
113 reg = <0xd0011000 0x20>;
114 #address-cells = <1>;
115 #size-cells = <0>;
116 interrupts = <31>;
117 timeout-ms = <1000>;
118 clocks = <&coreclk 0>;
119 status = "disabled";
120 };
121
122 i2c1: i2c@d0011100 {
123 compatible = "marvell,mv64xxx-i2c";
124 reg = <0xd0011100 0x20>;
125 #address-cells = <1>;
126 #size-cells = <0>;
127 interrupts = <32>;
128 timeout-ms = <1000>;
129 clocks = <&coreclk 0>;
130 status = "disabled";
131 };
71 }; 132 };
72}; 133};
73 134
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index 2069151afe01..636cf7d4009e 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -20,6 +20,12 @@
20/ { 20/ {
21 model = "Marvell Armada 370 family SoC"; 21 model = "Marvell Armada 370 family SoC";
22 compatible = "marvell,armada370", "marvell,armada-370-xp"; 22 compatible = "marvell,armada370", "marvell,armada-370-xp";
23 L2: l2-cache {
24 compatible = "marvell,aurora-outer-cache";
25 reg = <0xd0008000 0x1000>;
26 cache-id-part = <0x100>;
27 wt-override;
28 };
23 29
24 aliases { 30 aliases {
25 gpio0 = &gpio0; 31 gpio0 = &gpio0;
@@ -75,5 +81,56 @@
75 #interrupts-cells = <2>; 81 #interrupts-cells = <2>;
76 interrupts = <91>; 82 interrupts = <91>;
77 }; 83 };
84
85 coreclk: mvebu-sar@d0018230 {
86 compatible = "marvell,armada-370-core-clock";
87 reg = <0xd0018230 0x08>;
88 #clock-cells = <1>;
89 };
90
91 gateclk: clock-gating-control@d0018220 {
92 compatible = "marvell,armada-370-gating-clock";
93 reg = <0xd0018220 0x4>;
94 clocks = <&coreclk 0>;
95 #clock-cells = <1>;
96 };
97
98 xor@d0060800 {
99 compatible = "marvell,orion-xor";
100 reg = <0xd0060800 0x100
101 0xd0060A00 0x100>;
102 status = "okay";
103
104 xor00 {
105 interrupts = <51>;
106 dmacap,memcpy;
107 dmacap,xor;
108 };
109 xor01 {
110 interrupts = <52>;
111 dmacap,memcpy;
112 dmacap,xor;
113 dmacap,memset;
114 };
115 };
116
117 xor@d0060900 {
118 compatible = "marvell,orion-xor";
119 reg = <0xd0060900 0x100
120 0xd0060b00 0x100>;
121 status = "okay";
122
123 xor10 {
124 interrupts = <94>;
125 dmacap,memcpy;
126 dmacap,xor;
127 };
128 xor11 {
129 interrupts = <95>;
130 dmacap,memcpy;
131 dmacap,xor;
132 dmacap,memset;
133 };
134 };
78 }; 135 };
79}; 136};
diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts
index b1fc728515e9..8e53b25b5508 100644
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -46,5 +46,49 @@
46 clock-frequency = <250000000>; 46 clock-frequency = <250000000>;
47 status = "okay"; 47 status = "okay";
48 }; 48 };
49
50 sata@d00a0000 {
51 nr-ports = <2>;
52 status = "okay";
53 };
54
55 mdio {
56 phy0: ethernet-phy@0 {
57 reg = <0>;
58 };
59
60 phy1: ethernet-phy@1 {
61 reg = <1>;
62 };
63
64 phy2: ethernet-phy@2 {
65 reg = <25>;
66 };
67
68 phy3: ethernet-phy@3 {
69 reg = <27>;
70 };
71 };
72
73 ethernet@d0070000 {
74 status = "okay";
75 phy = <&phy0>;
76 phy-mode = "rgmii-id";
77 };
78 ethernet@d0074000 {
79 status = "okay";
80 phy = <&phy1>;
81 phy-mode = "rgmii-id";
82 };
83 ethernet@d0030000 {
84 status = "okay";
85 phy = <&phy2>;
86 phy-mode = "sgmii";
87 };
88 ethernet@d0034000 {
89 status = "okay";
90 phy = <&phy3>;
91 phy-mode = "sgmii";
92 };
49 }; 93 };
50}; 94};
diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
index ea355192be6f..c45c7b4dc352 100644
--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
@@ -24,6 +24,18 @@
24 gpio1 = &gpio1; 24 gpio1 = &gpio1;
25 }; 25 };
26 26
27 cpus {
28 #address-cells = <1>;
29 #size-cells = <0>;
30
31 cpu@0 {
32 device_type = "cpu";
33 compatible = "marvell,sheeva-v7";
34 reg = <0>;
35 clocks = <&cpuclk 0>;
36 };
37 }
38
27 soc { 39 soc {
28 pinctrl { 40 pinctrl {
29 compatible = "marvell,mv78230-pinctrl"; 41 compatible = "marvell,mv78230-pinctrl";
diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
index 2057863f3dfa..a2aee5707377 100644
--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
@@ -25,6 +25,25 @@
25 gpio2 = &gpio2; 25 gpio2 = &gpio2;
26 }; 26 };
27 27
28 cpus {
29 #address-cells = <1>;
30 #size-cells = <0>;
31
32 cpu@0 {
33 device_type = "cpu";
34 compatible = "marvell,sheeva-v7";
35 reg = <0>;
36 clocks = <&cpuclk 0>;
37 };
38
39 cpu@1 {
40 device_type = "cpu";
41 compatible = "marvell,sheeva-v7";
42 reg = <1>;
43 clocks = <&cpuclk 1>;
44 };
45 };
46
28 soc { 47 soc {
29 pinctrl { 48 pinctrl {
30 compatible = "marvell,mv78260-pinctrl"; 49 compatible = "marvell,mv78260-pinctrl";
diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
index ffac98373792..da03a129243a 100644
--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
@@ -25,6 +25,40 @@
25 gpio2 = &gpio2; 25 gpio2 = &gpio2;
26 }; 26 };
27 27
28
29 cpus {
30 #address-cells = <1>;
31 #size-cells = <0>;
32
33 cpu@0 {
34 device_type = "cpu";
35 compatible = "marvell,sheeva-v7";
36 reg = <0>;
37 clocks = <&cpuclk 0>;
38 };
39
40 cpu@1 {
41 device_type = "cpu";
42 compatible = "marvell,sheeva-v7";
43 reg = <1>;
44 clocks = <&cpuclk 1>;
45 };
46
47 cpu@2 {
48 device_type = "cpu";
49 compatible = "marvell,sheeva-v7";
50 reg = <2>;
51 clocks = <&cpuclk 2>;
52 };
53
54 cpu@3 {
55 device_type = "cpu";
56 compatible = "marvell,sheeva-v7";
57 reg = <3>;
58 clocks = <&cpuclk 3>;
59 };
60 };
61
28 soc { 62 soc {
29 pinctrl { 63 pinctrl {
30 compatible = "marvell,mv78460-pinctrl"; 64 compatible = "marvell,mv78460-pinctrl";
diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
new file mode 100644
index 000000000000..b42652fd3d8c
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -0,0 +1,125 @@
1/*
2 * Device Tree file for OpenBlocks AX3-4 board
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Thomas Petazzoni <thomas.petazzoni@free-electrons.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/dts-v1/;
14/include/ "armada-xp-mv78260.dtsi"
15
16/ {
17 model = "PlatHome OpenBlocks AX3-4 board";
18 compatible = "plathome,openblocks-ax3-4", "marvell,armadaxp-mv78260", "marvell,armadaxp", "marvell,armada-370-xp";
19
20 chosen {
21 bootargs = "console=ttyS0,115200 earlyprintk";
22 };
23
24 memory {
25 device_type = "memory";
26 reg = <0x00000000 0xC0000000>; /* 3 GB */
27 };
28
29 soc {
30 serial@d0012000 {
31 clock-frequency = <250000000>;
32 status = "okay";
33 };
34 serial@d0012100 {
35 clock-frequency = <250000000>;
36 status = "okay";
37 };
38 pinctrl {
39 led_pins: led-pins-0 {
40 marvell,pins = "mpp49", "mpp51", "mpp53";
41 marvell,function = "gpio";
42 };
43 };
44 leds {
45 compatible = "gpio-leds";
46 pinctrl-names = "default";
47 pinctrl-0 = <&led_pins>;
48
49 red_led {
50 label = "red_led";
51 gpios = <&gpio1 17 1>;
52 default-state = "off";
53 };
54
55 yellow_led {
56 label = "yellow_led";
57 gpios = <&gpio1 19 1>;
58 default-state = "off";
59 };
60
61 green_led {
62 label = "green_led";
63 gpios = <&gpio1 21 1>;
64 default-state = "off";
65 linux,default-trigger = "heartbeat";
66 };
67 };
68
69 mdio {
70 phy0: ethernet-phy@0 {
71 reg = <0>;
72 };
73
74 phy1: ethernet-phy@1 {
75 reg = <1>;
76 };
77
78 phy2: ethernet-phy@2 {
79 reg = <2>;
80 };
81
82 phy3: ethernet-phy@3 {
83 reg = <3>;
84 };
85 };
86
87 ethernet@d0070000 {
88 status = "okay";
89 phy = <&phy0>;
90 phy-mode = "sgmii";
91 };
92 ethernet@d0074000 {
93 status = "okay";
94 phy = <&phy1>;
95 phy-mode = "sgmii";
96 };
97 ethernet@d0030000 {
98 status = "okay";
99 phy = <&phy2>;
100 phy-mode = "sgmii";
101 };
102 ethernet@d0034000 {
103 status = "okay";
104 phy = <&phy3>;
105 phy-mode = "sgmii";
106 };
107 i2c@d0011000 {
108 status = "okay";
109 clock-frequency = <400000>;
110 };
111 i2c@d0011100 {
112 status = "okay";
113 clock-frequency = <400000>;
114
115 s35390a: s35390a@30 {
116 compatible = "s35390a";
117 reg = <0x30>;
118 };
119 };
120 sata@d00a0000 {
121 nr-ports = <2>;
122 status = "okay";
123 };
124 };
125};
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index 71d6b5d0daf1..367aa3f94912 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -22,9 +22,22 @@
22 model = "Marvell Armada XP family SoC"; 22 model = "Marvell Armada XP family SoC";
23 compatible = "marvell,armadaxp", "marvell,armada-370-xp"; 23 compatible = "marvell,armadaxp", "marvell,armada-370-xp";
24 24
25 L2: l2-cache {
26 compatible = "marvell,aurora-system-cache";
27 reg = <0xd0008000 0x1000>;
28 cache-id-part = <0x100>;
29 wt-override;
30 };
31
25 mpic: interrupt-controller@d0020000 { 32 mpic: interrupt-controller@d0020000 {
26 reg = <0xd0020a00 0x1d0>, 33 reg = <0xd0020a00 0x1d0>,
27 <0xd0021870 0x58>; 34 <0xd0021070 0x58>;
35 };
36
37 armada-370-xp-pmsu@d0022000 {
38 compatible = "marvell,armada-370-xp-pmsu";
39 reg = <0xd0022100 0x430>,
40 <0xd0020800 0x20>;
28 }; 41 };
29 42
30 soc { 43 soc {
@@ -47,9 +60,85 @@
47 marvell,timer-25Mhz; 60 marvell,timer-25Mhz;
48 }; 61 };
49 62
63 coreclk: mvebu-sar@d0018230 {
64 compatible = "marvell,armada-xp-core-clock";
65 reg = <0xd0018230 0x08>;
66 #clock-cells = <1>;
67 };
68
69 cpuclk: clock-complex@d0018700 {
70 #clock-cells = <1>;
71 compatible = "marvell,armada-xp-cpu-clock";
72 reg = <0xd0018700 0xA0>;
73 clocks = <&coreclk 1>;
74 };
75
76 gateclk: clock-gating-control@d0018220 {
77 compatible = "marvell,armada-xp-gating-clock";
78 reg = <0xd0018220 0x4>;
79 clocks = <&coreclk 0>;
80 #clock-cells = <1>;
81 };
82
50 system-controller@d0018200 { 83 system-controller@d0018200 {
51 compatible = "marvell,armada-370-xp-system-controller"; 84 compatible = "marvell,armada-370-xp-system-controller";
52 reg = <0xd0018200 0x500>; 85 reg = <0xd0018200 0x500>;
53 }; 86 };
87
88 ethernet@d0030000 {
89 compatible = "marvell,armada-370-neta";
90 reg = <0xd0030000 0x2500>;
91 interrupts = <12>;
92 clocks = <&gateclk 2>;
93 status = "disabled";
94 };
95
96 ethernet@d0034000 {
97 compatible = "marvell,armada-370-neta";
98 reg = <0xd0034000 0x2500>;
99 interrupts = <14>;
100 clocks = <&gateclk 1>;
101 status = "disabled";
102 };
103
104 xor@d0060900 {
105 compatible = "marvell,orion-xor";
106 reg = <0xd0060900 0x100
107 0xd0060b00 0x100>;
108 clocks = <&gateclk 22>;
109 status = "okay";
110
111 xor10 {
112 interrupts = <51>;
113 dmacap,memcpy;
114 dmacap,xor;
115 };
116 xor11 {
117 interrupts = <52>;
118 dmacap,memcpy;
119 dmacap,xor;
120 dmacap,memset;
121 };
122 };
123
124 xor@d00f0900 {
125 compatible = "marvell,orion-xor";
126 reg = <0xd00F0900 0x100
127 0xd00F0B00 0x100>;
128 clocks = <&gateclk 28>;
129 status = "okay";
130
131 xor00 {
132 interrupts = <94>;
133 dmacap,memcpy;
134 dmacap,xor;
135 };
136 xor01 {
137 interrupts = <95>;
138 dmacap,memcpy;
139 dmacap,xor;
140 dmacap,memset;
141 };
142 };
54 }; 143 };
55}; 144};
diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
index 61f391412a5a..f3f7e9d8adca 100644
--- a/arch/arm/boot/dts/dove.dtsi
+++ b/arch/arm/boot/dts/dove.dtsi
@@ -37,6 +37,19 @@
37 reg = <0x20204 0x04>, <0x20214 0x04>; 37 reg = <0x20204 0x04>, <0x20214 0x04>;
38 }; 38 };
39 39
40 core_clk: core-clocks@d0214 {
41 compatible = "marvell,dove-core-clock";
42 reg = <0xd0214 0x4>;
43 #clock-cells = <1>;
44 };
45
46 gate_clk: clock-gating-control@d0038 {
47 compatible = "marvell,dove-gating-clock";
48 reg = <0xd0038 0x4>;
49 clocks = <&core_clk 0>;
50 #clock-cells = <1>;
51 };
52
40 uart0: serial@12000 { 53 uart0: serial@12000 {
41 compatible = "ns16550a"; 54 compatible = "ns16550a";
42 reg = <0x12000 0x100>; 55 reg = <0x12000 0x100>;
@@ -113,6 +126,7 @@
113 cell-index = <0>; 126 cell-index = <0>;
114 interrupts = <6>; 127 interrupts = <6>;
115 reg = <0x10600 0x28>; 128 reg = <0x10600 0x28>;
129 clocks = <&core_clk 0>;
116 status = "disabled"; 130 status = "disabled";
117 }; 131 };
118 132
@@ -123,6 +137,7 @@
123 cell-index = <1>; 137 cell-index = <1>;
124 interrupts = <5>; 138 interrupts = <5>;
125 reg = <0x14600 0x28>; 139 reg = <0x14600 0x28>;
140 clocks = <&core_clk 0>;
126 status = "disabled"; 141 status = "disabled";
127 }; 142 };
128 143
@@ -134,6 +149,7 @@
134 interrupts = <11>; 149 interrupts = <11>;
135 clock-frequency = <400000>; 150 clock-frequency = <400000>;
136 timeout-ms = <1000>; 151 timeout-ms = <1000>;
152 clocks = <&core_clk 0>;
137 status = "disabled"; 153 status = "disabled";
138 }; 154 };
139 155
@@ -141,6 +157,7 @@
141 compatible = "marvell,dove-sdhci"; 157 compatible = "marvell,dove-sdhci";
142 reg = <0x92000 0x100>; 158 reg = <0x92000 0x100>;
143 interrupts = <35>, <37>; 159 interrupts = <35>, <37>;
160 clocks = <&gate_clk 8>;
144 status = "disabled"; 161 status = "disabled";
145 }; 162 };
146 163
@@ -148,6 +165,7 @@
148 compatible = "marvell,dove-sdhci"; 165 compatible = "marvell,dove-sdhci";
149 reg = <0x90000 0x100>; 166 reg = <0x90000 0x100>;
150 interrupts = <36>, <38>; 167 interrupts = <36>, <38>;
168 clocks = <&gate_clk 9>;
151 status = "disabled"; 169 status = "disabled";
152 }; 170 };
153 171
@@ -155,6 +173,7 @@
155 compatible = "marvell,orion-sata"; 173 compatible = "marvell,orion-sata";
156 reg = <0xa0000 0x2400>; 174 reg = <0xa0000 0x2400>;
157 interrupts = <62>; 175 interrupts = <62>;
176 clocks = <&gate_clk 3>;
158 nr-ports = <1>; 177 nr-ports = <1>;
159 status = "disabled"; 178 status = "disabled";
160 }; 179 };
@@ -165,7 +184,50 @@
165 <0xc8000000 0x800>; 184 <0xc8000000 0x800>;
166 reg-names = "regs", "sram"; 185 reg-names = "regs", "sram";
167 interrupts = <31>; 186 interrupts = <31>;
187 clocks = <&gate_clk 15>;
188 status = "okay";
189 };
190
191 xor0: dma-engine@60800 {
192 compatible = "marvell,orion-xor";
193 reg = <0x60800 0x100
194 0x60a00 0x100>;
195 clocks = <&gate_clk 23>;
168 status = "okay"; 196 status = "okay";
197
198 channel0 {
199 interrupts = <39>;
200 dmacap,memcpy;
201 dmacap,xor;
202 };
203
204 channel1 {
205 interrupts = <40>;
206 dmacap,memset;
207 dmacap,memcpy;
208 dmacap,xor;
209 };
210 };
211
212 xor1: dma-engine@60900 {
213 compatible = "marvell,orion-xor";
214 reg = <0x60900 0x100
215 0x60b00 0x100>;
216 clocks = <&gate_clk 24>;
217 status = "okay";
218
219 channel0 {
220 interrupts = <42>;
221 dmacap,memcpy;
222 dmacap,xor;
223 };
224
225 channel1 {
226 interrupts = <43>;
227 dmacap,memset;
228 dmacap,memcpy;
229 dmacap,xor;
230 };
169 }; 231 };
170 }; 232 };
171}; 233};
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index a990c30f0a26..7735cee4a9c6 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -23,6 +23,12 @@
23 #address-cells = <1>; 23 #address-cells = <1>;
24 #size-cells = <1>; 24 #size-cells = <1>;
25 25
26 core_clk: core-clocks@10030 {
27 compatible = "marvell,kirkwood-core-clock";
28 reg = <0x10030 0x4>;
29 #clock-cells = <1>;
30 };
31
26 gpio0: gpio@10100 { 32 gpio0: gpio@10100 {
27 compatible = "marvell,orion-gpio"; 33 compatible = "marvell,orion-gpio";
28 #gpio-cells = <2>; 34 #gpio-cells = <2>;
@@ -48,6 +54,7 @@
48 reg = <0x12000 0x100>; 54 reg = <0x12000 0x100>;
49 reg-shift = <2>; 55 reg-shift = <2>;
50 interrupts = <33>; 56 interrupts = <33>;
57 clocks = <&gate_clk 7>;
51 /* set clock-frequency in board dts */ 58 /* set clock-frequency in board dts */
52 status = "disabled"; 59 status = "disabled";
53 }; 60 };
@@ -57,6 +64,7 @@
57 reg = <0x12100 0x100>; 64 reg = <0x12100 0x100>;
58 reg-shift = <2>; 65 reg-shift = <2>;
59 interrupts = <34>; 66 interrupts = <34>;
67 clocks = <&gate_clk 7>;
60 /* set clock-frequency in board dts */ 68 /* set clock-frequency in board dts */
61 status = "disabled"; 69 status = "disabled";
62 }; 70 };
@@ -74,13 +82,62 @@
74 cell-index = <0>; 82 cell-index = <0>;
75 interrupts = <23>; 83 interrupts = <23>;
76 reg = <0x10600 0x28>; 84 reg = <0x10600 0x28>;
85 clocks = <&gate_clk 7>;
77 status = "disabled"; 86 status = "disabled";
78 }; 87 };
79 88
89 gate_clk: clock-gating-control@2011c {
90 compatible = "marvell,kirkwood-gating-clock";
91 reg = <0x2011c 0x4>;
92 clocks = <&core_clk 0>;
93 #clock-cells = <1>;
94 };
95
80 wdt@20300 { 96 wdt@20300 {
81 compatible = "marvell,orion-wdt"; 97 compatible = "marvell,orion-wdt";
82 reg = <0x20300 0x28>; 98 reg = <0x20300 0x28>;
99 clocks = <&gate_clk 7>;
100 status = "okay";
101 };
102
103 xor@60800 {
104 compatible = "marvell,orion-xor";
105 reg = <0x60800 0x100
106 0x60A00 0x100>;
107 status = "okay";
108 clocks = <&gate_clk 8>;
109
110 xor00 {
111 interrupts = <5>;
112 dmacap,memcpy;
113 dmacap,xor;
114 };
115 xor01 {
116 interrupts = <6>;
117 dmacap,memcpy;
118 dmacap,xor;
119 dmacap,memset;
120 };
121 };
122
123 xor@60900 {
124 compatible = "marvell,orion-xor";
125 reg = <0x60900 0x100
126 0xd0B00 0x100>;
83 status = "okay"; 127 status = "okay";
128 clocks = <&gate_clk 16>;
129
130 xor00 {
131 interrupts = <7>;
132 dmacap,memcpy;
133 dmacap,xor;
134 };
135 xor01 {
136 interrupts = <8>;
137 dmacap,memcpy;
138 dmacap,xor;
139 dmacap,memset;
140 };
84 }; 141 };
85 142
86 ehci@50000 { 143 ehci@50000 {
@@ -94,6 +151,8 @@
94 compatible = "marvell,orion-sata"; 151 compatible = "marvell,orion-sata";
95 reg = <0x80000 0x5000>; 152 reg = <0x80000 0x5000>;
96 interrupts = <21>; 153 interrupts = <21>;
154 clocks = <&gate_clk 14>, <&gate_clk 15>;
155 clock-names = "0", "1";
97 status = "disabled"; 156 status = "disabled";
98 }; 157 };
99 158
@@ -107,6 +166,7 @@
107 reg = <0x3000000 0x400>; 166 reg = <0x3000000 0x400>;
108 chip-delay = <25>; 167 chip-delay = <25>;
109 /* set partition map and/or chip-delay in board dts */ 168 /* set partition map and/or chip-delay in board dts */
169 clocks = <&gate_clk 7>;
110 status = "disabled"; 170 status = "disabled";
111 }; 171 };
112 172
@@ -117,6 +177,7 @@
117 #size-cells = <0>; 177 #size-cells = <0>;
118 interrupts = <29>; 178 interrupts = <29>;
119 clock-frequency = <100000>; 179 clock-frequency = <100000>;
180 clocks = <&gate_clk 7>;
120 status = "disabled"; 181 status = "disabled";
121 }; 182 };
122 183
@@ -126,6 +187,7 @@
126 <0xf5000000 0x800>; 187 <0xf5000000 0x800>;
127 reg-names = "regs", "sram"; 188 reg-names = "regs", "sram";
128 interrupts = <22>; 189 interrupts = <22>;
190 clocks = <&gate_clk 17>;
129 status = "okay"; 191 status = "okay";
130 }; 192 };
131 }; 193 };
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 159f75fc4377..dbea6f4efe9f 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -17,8 +17,10 @@ CONFIG_ARM_APPENDED_DTB=y
17CONFIG_VFP=y 17CONFIG_VFP=y
18CONFIG_NEON=y 18CONFIG_NEON=y
19CONFIG_NET=y 19CONFIG_NET=y
20CONFIG_BLK_DEV_SD=y
20CONFIG_ATA=y 21CONFIG_ATA=y
21CONFIG_SATA_HIGHBANK=y 22CONFIG_SATA_HIGHBANK=y
23CONFIG_SATA_MV=y
22CONFIG_NETDEVICES=y 24CONFIG_NETDEVICES=y
23CONFIG_NET_CALXEDA_XGMAC=y 25CONFIG_NET_CALXEDA_XGMAC=y
24CONFIG_SMSC911X=y 26CONFIG_SMSC911X=y
diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig
index 3458752c4bb2..a702fb345c01 100644
--- a/arch/arm/configs/mvebu_defconfig
+++ b/arch/arm/configs/mvebu_defconfig
@@ -12,6 +12,9 @@ CONFIG_ARCH_MVEBU=y
12CONFIG_MACH_ARMADA_370=y 12CONFIG_MACH_ARMADA_370=y
13CONFIG_MACH_ARMADA_XP=y 13CONFIG_MACH_ARMADA_XP=y
14# CONFIG_CACHE_L2X0 is not set 14# CONFIG_CACHE_L2X0 is not set
15# CONFIG_SWP_EMULATE is not set
16CONFIG_SMP=y
17# CONFIG_LOCAL_TIMERS is not set
15CONFIG_AEABI=y 18CONFIG_AEABI=y
16CONFIG_HIGHMEM=y 19CONFIG_HIGHMEM=y
17# CONFIG_COMPACTION is not set 20# CONFIG_COMPACTION is not set
@@ -19,13 +22,27 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
19CONFIG_ZBOOT_ROM_BSS=0x0 22CONFIG_ZBOOT_ROM_BSS=0x0
20CONFIG_ARM_APPENDED_DTB=y 23CONFIG_ARM_APPENDED_DTB=y
21CONFIG_VFP=y 24CONFIG_VFP=y
25CONFIG_NET=y
26CONFIG_INET=y
22CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 27CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
28CONFIG_BLK_DEV_SD=y
29CONFIG_ATA=y
30CONFIG_SATA_MV=y
31CONFIG_NETDEVICES=y
32CONFIG_MVNETA=y
33CONFIG_MARVELL_PHY=y
23CONFIG_SERIAL_8250=y 34CONFIG_SERIAL_8250=y
24CONFIG_SERIAL_8250_CONSOLE=y 35CONFIG_SERIAL_8250_CONSOLE=y
25CONFIG_SERIAL_OF_PLATFORM=y 36CONFIG_SERIAL_OF_PLATFORM=y
37CONFIG_I2C=y
38CONFIG_I2C_MV64XXX=y
26CONFIG_GPIOLIB=y 39CONFIG_GPIOLIB=y
27CONFIG_GPIO_SYSFS=y 40CONFIG_GPIO_SYSFS=y
28# CONFIG_USB_SUPPORT is not set 41# CONFIG_USB_SUPPORT is not set
42CONFIG_RTC_CLASS=y
43CONFIG_RTC_DRV_S35390A=y
44CONFIG_DMADEVICES=y
45CONFIG_MV_XOR=y
29# CONFIG_IOMMU_SUPPORT is not set 46# CONFIG_IOMMU_SUPPORT is not set
30CONFIG_EXT2_FS=y 47CONFIG_EXT2_FS=y
31CONFIG_EXT3_FS=y 48CONFIG_EXT3_FS=y
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 8ea02ac3ec1a..67d06324e74a 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -111,6 +111,8 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size,
111 111
112extern int dma_supported(struct device *dev, u64 mask); 112extern int dma_supported(struct device *dev, u64 mask);
113 113
114extern int arm_dma_set_mask(struct device *dev, u64 dma_mask);
115
114/** 116/**
115 * arm_dma_alloc - allocate consistent memory for DMA 117 * arm_dma_alloc - allocate consistent memory for DMA
116 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices 118 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig
index 00154e74ce6b..603c5fd99e8a 100644
--- a/arch/arm/mach-dove/Kconfig
+++ b/arch/arm/mach-dove/Kconfig
@@ -17,6 +17,8 @@ config MACH_CM_A510
17 17
18config MACH_DOVE_DT 18config MACH_DOVE_DT
19 bool "Marvell Dove Flattened Device Tree" 19 bool "Marvell Dove Flattened Device Tree"
20 select MVEBU_CLK_CORE
21 select MVEBU_CLK_GATING
20 select USE_OF 22 select USE_OF
21 help 23 help
22 Say 'Y' here if you want your kernel to support the 24 Say 'Y' here if you want your kernel to support the
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
index f723fe13d0f0..89f4f993cd03 100644
--- a/arch/arm/mach-dove/common.c
+++ b/arch/arm/mach-dove/common.c
@@ -14,6 +14,7 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/pci.h> 15#include <linux/pci.h>
16#include <linux/clk-provider.h> 16#include <linux/clk-provider.h>
17#include <linux/clk/mvebu.h>
17#include <linux/ata_platform.h> 18#include <linux/ata_platform.h>
18#include <linux/gpio.h> 19#include <linux/gpio.h>
19#include <linux/of.h> 20#include <linux/of.h>
@@ -32,6 +33,7 @@
32#include <linux/irq.h> 33#include <linux/irq.h>
33#include <plat/time.h> 34#include <plat/time.h>
34#include <linux/platform_data/usb-ehci-orion.h> 35#include <linux/platform_data/usb-ehci-orion.h>
36#include <linux/platform_data/dma-mv_xor.h>
35#include <plat/irq.h> 37#include <plat/irq.h>
36#include <plat/common.h> 38#include <plat/common.h>
37#include <plat/addr-map.h> 39#include <plat/addr-map.h>
@@ -123,8 +125,8 @@ static void __init dove_clk_init(void)
123 orion_clkdev_add(NULL, "mv_crypto", crypto); 125 orion_clkdev_add(NULL, "mv_crypto", crypto);
124 orion_clkdev_add(NULL, "dove-ac97", ac97); 126 orion_clkdev_add(NULL, "dove-ac97", ac97);
125 orion_clkdev_add(NULL, "dove-pdma", pdma); 127 orion_clkdev_add(NULL, "dove-pdma", pdma);
126 orion_clkdev_add(NULL, "mv_xor_shared.0", xor0); 128 orion_clkdev_add(NULL, MV_XOR_NAME ".0", xor0);
127 orion_clkdev_add(NULL, "mv_xor_shared.1", xor1); 129 orion_clkdev_add(NULL, MV_XOR_NAME ".1", xor1);
128} 130}
129 131
130/***************************************************************************** 132/*****************************************************************************
@@ -376,19 +378,44 @@ void dove_restart(char mode, const char *cmd)
376 378
377#if defined(CONFIG_MACH_DOVE_DT) 379#if defined(CONFIG_MACH_DOVE_DT)
378/* 380/*
379 * Auxdata required until real OF clock provider 381 * There are still devices that doesn't even know about DT,
382 * get clock gates here and add a clock lookup.
380 */ 383 */
381struct of_dev_auxdata dove_auxdata_lookup[] __initdata = { 384static void __init dove_legacy_clk_init(void)
382 OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL), 385{
383 OF_DEV_AUXDATA("marvell,orion-spi", 0xf1014600, "orion_spi.1", NULL), 386 struct device_node *np = of_find_compatible_node(NULL, NULL,
384 OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL), 387 "marvell,dove-gating-clock");
385 OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0", 388 struct of_phandle_args clkspec;
386 NULL), 389
387 OF_DEV_AUXDATA("marvell,orion-sata", 0xf10a0000, "sata_mv.0", NULL), 390 clkspec.np = np;
388 OF_DEV_AUXDATA("marvell,dove-sdhci", 0xf1092000, "sdhci-dove.0", NULL), 391 clkspec.args_count = 1;
389 OF_DEV_AUXDATA("marvell,dove-sdhci", 0xf1090000, "sdhci-dove.1", NULL), 392
390 {}, 393 clkspec.args[0] = CLOCK_GATING_BIT_USB0;
391}; 394 orion_clkdev_add(NULL, "orion-ehci.0",
395 of_clk_get_from_provider(&clkspec));
396
397 clkspec.args[0] = CLOCK_GATING_BIT_USB1;
398 orion_clkdev_add(NULL, "orion-ehci.1",
399 of_clk_get_from_provider(&clkspec));
400
401 clkspec.args[0] = CLOCK_GATING_BIT_GBE;
402 orion_clkdev_add(NULL, "mv643xx_eth_port.0",
403 of_clk_get_from_provider(&clkspec));
404
405 clkspec.args[0] = CLOCK_GATING_BIT_PCIE0;
406 orion_clkdev_add("0", "pcie",
407 of_clk_get_from_provider(&clkspec));
408
409 clkspec.args[0] = CLOCK_GATING_BIT_PCIE1;
410 orion_clkdev_add("1", "pcie",
411 of_clk_get_from_provider(&clkspec));
412}
413
414static void __init dove_of_clk_init(void)
415{
416 mvebu_clocks_init();
417 dove_legacy_clk_init();
418}
392 419
393static struct mv643xx_eth_platform_data dove_dt_ge00_data = { 420static struct mv643xx_eth_platform_data dove_dt_ge00_data = {
394 .phy_addr = MV643XX_ETH_PHY_ADDR_DEFAULT, 421 .phy_addr = MV643XX_ETH_PHY_ADDR_DEFAULT,
@@ -405,20 +432,17 @@ static void __init dove_dt_init(void)
405 dove_setup_cpu_mbus(); 432 dove_setup_cpu_mbus();
406 433
407 /* Setup root of clk tree */ 434 /* Setup root of clk tree */
408 dove_clk_init(); 435 dove_of_clk_init();
409 436
410 /* Internal devices not ported to DT yet */ 437 /* Internal devices not ported to DT yet */
411 dove_rtc_init(); 438 dove_rtc_init();
412 dove_xor0_init();
413 dove_xor1_init();
414 439
415 dove_ge00_init(&dove_dt_ge00_data); 440 dove_ge00_init(&dove_dt_ge00_data);
416 dove_ehci0_init(); 441 dove_ehci0_init();
417 dove_ehci1_init(); 442 dove_ehci1_init();
418 dove_pcie_init(1, 1); 443 dove_pcie_init(1, 1);
419 444
420 of_platform_populate(NULL, of_default_bus_match_table, 445 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
421 dove_auxdata_lookup, NULL);
422} 446}
423 447
424static const char * const dove_dt_board_compat[] = { 448static const char * const dove_dt_board_compat[] = {
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index 503d7dd944ff..f91cdff5a3e4 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -51,6 +51,8 @@ config ARCH_KIRKWOOD_DT
51 select POWER_RESET_GPIO 51 select POWER_RESET_GPIO
52 select REGULATOR 52 select REGULATOR
53 select REGULATOR_FIXED_VOLTAGE 53 select REGULATOR_FIXED_VOLTAGE
54 select MVEBU_CLK_CORE
55 select MVEBU_CLK_GATING
54 select USE_OF 56 select USE_OF
55 help 57 help
56 Say 'Y' here if you want your kernel to support the 58 Say 'Y' here if you want your kernel to support the
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index 375f7d88551c..ff4150a2ad05 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -14,11 +14,15 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/of_platform.h> 16#include <linux/of_platform.h>
17#include <linux/clk-provider.h>
18#include <linux/clk/mvebu.h>
17#include <linux/kexec.h> 19#include <linux/kexec.h>
18#include <asm/mach/arch.h> 20#include <asm/mach/arch.h>
19#include <asm/mach/map.h> 21#include <asm/mach/map.h>
20#include <mach/bridge-regs.h> 22#include <mach/bridge-regs.h>
23#include <linux/platform_data/usb-ehci-orion.h>
21#include <plat/irq.h> 24#include <plat/irq.h>
25#include <plat/common.h>
22#include "common.h" 26#include "common.h"
23 27
24static struct of_device_id kirkwood_dt_match_table[] __initdata = { 28static struct of_device_id kirkwood_dt_match_table[] __initdata = {
@@ -26,18 +30,50 @@ static struct of_device_id kirkwood_dt_match_table[] __initdata = {
26 { } 30 { }
27}; 31};
28 32
29static struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = { 33/*
30 OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL), 34 * There are still devices that doesn't know about DT yet. Get clock
31 OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0", 35 * gates here and add a clock lookup alias, so that old platform
32 NULL), 36 * devices still work.
33 OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011100, "mv64xxx_i2c.1", 37*/
34 NULL), 38
35 OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL), 39static void __init kirkwood_legacy_clk_init(void)
36 OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL), 40{
37 OF_DEV_AUXDATA("marvell,orion-nand", 0xf4000000, "orion_nand", NULL), 41
38 OF_DEV_AUXDATA("marvell,orion-crypto", 0xf1030000, "mv_crypto", NULL), 42 struct device_node *np = of_find_compatible_node(
39 {}, 43 NULL, NULL, "marvell,kirkwood-gating-clock");
40}; 44
45 struct of_phandle_args clkspec;
46
47 clkspec.np = np;
48 clkspec.args_count = 1;
49
50 clkspec.args[0] = CGC_BIT_GE0;
51 orion_clkdev_add(NULL, "mv643xx_eth_port.0",
52 of_clk_get_from_provider(&clkspec));
53
54 clkspec.args[0] = CGC_BIT_PEX0;
55 orion_clkdev_add("0", "pcie",
56 of_clk_get_from_provider(&clkspec));
57
58 clkspec.args[0] = CGC_BIT_USB0;
59 orion_clkdev_add(NULL, "orion-ehci.0",
60 of_clk_get_from_provider(&clkspec));
61
62 clkspec.args[0] = CGC_BIT_PEX1;
63 orion_clkdev_add("1", "pcie",
64 of_clk_get_from_provider(&clkspec));
65
66 clkspec.args[0] = CGC_BIT_GE1;
67 orion_clkdev_add(NULL, "mv643xx_eth_port.1",
68 of_clk_get_from_provider(&clkspec));
69
70}
71
72static void __init kirkwood_of_clk_init(void)
73{
74 mvebu_clocks_init();
75 kirkwood_legacy_clk_init();
76}
41 77
42static void __init kirkwood_dt_init(void) 78static void __init kirkwood_dt_init(void)
43{ 79{
@@ -56,11 +92,7 @@ static void __init kirkwood_dt_init(void)
56 kirkwood_l2_init(); 92 kirkwood_l2_init();
57 93
58 /* Setup root of clk tree */ 94 /* Setup root of clk tree */
59 kirkwood_clk_init(); 95 kirkwood_of_clk_init();
60
61 /* internal devices that every board has */
62 kirkwood_xor0_init();
63 kirkwood_xor1_init();
64 96
65#ifdef CONFIG_KEXEC 97#ifdef CONFIG_KEXEC
66 kexec_reinit = kirkwood_enable_pcie; 98 kexec_reinit = kirkwood_enable_pcie;
@@ -115,8 +147,7 @@ static void __init kirkwood_dt_init(void)
115 if (of_machine_is_compatible("zyxel,nsa310")) 147 if (of_machine_is_compatible("zyxel,nsa310"))
116 nsa310_init(); 148 nsa310_init();
117 149
118 of_platform_populate(NULL, kirkwood_dt_match_table, 150 of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL);
119 kirkwood_auxdata_lookup, NULL);
120} 151}
121 152
122static const char * const kirkwood_dt_board_compat[] = { 153static const char * const kirkwood_dt_board_compat[] = {
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 5303be62b311..bac21a554c91 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -260,8 +260,8 @@ void __init kirkwood_clk_init(void)
260 orion_clkdev_add(NULL, "orion_nand", runit); 260 orion_clkdev_add(NULL, "orion_nand", runit);
261 orion_clkdev_add(NULL, "mvsdio", sdio); 261 orion_clkdev_add(NULL, "mvsdio", sdio);
262 orion_clkdev_add(NULL, "mv_crypto", crypto); 262 orion_clkdev_add(NULL, "mv_crypto", crypto);
263 orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".0", xor0); 263 orion_clkdev_add(NULL, MV_XOR_NAME ".0", xor0);
264 orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".1", xor1); 264 orion_clkdev_add(NULL, MV_XOR_NAME ".1", xor1);
265 orion_clkdev_add("0", "pcie", pex0); 265 orion_clkdev_add("0", "pcie", pex0);
266 orion_clkdev_add("1", "pcie", pex1); 266 orion_clkdev_add("1", "pcie", pex1);
267 orion_clkdev_add(NULL, "kirkwood-i2s", audio); 267 orion_clkdev_add(NULL, "kirkwood-i2s", audio);
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 416d46ef7ebd..440b13ef1fed 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -9,6 +9,10 @@ config ARCH_MVEBU
9 select PINCTRL 9 select PINCTRL
10 select PLAT_ORION 10 select PLAT_ORION
11 select SPARSE_IRQ 11 select SPARSE_IRQ
12 select CLKDEV_LOOKUP
13 select MVEBU_CLK_CORE
14 select MVEBU_CLK_CPU
15 select MVEBU_CLK_GATING
12 16
13if ARCH_MVEBU 17if ARCH_MVEBU
14 18
@@ -17,7 +21,9 @@ menu "Marvell SOC with device tree"
17config MACH_ARMADA_370_XP 21config MACH_ARMADA_370_XP
18 bool 22 bool
19 select ARMADA_370_XP_TIMER 23 select ARMADA_370_XP_TIMER
20 select CPU_V7 24 select HAVE_SMP
25 select CACHE_L2X0
26 select CPU_PJ4B
21 27
22config MACH_ARMADA_370 28config MACH_ARMADA_370
23 bool "Marvell Armada 370 boards" 29 bool "Marvell Armada 370 boards"
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index 57f996b6aa0e..5dcb369b58aa 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -2,4 +2,6 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
2 -I$(srctree)/arch/arm/plat-orion/include 2 -I$(srctree)/arch/arm/plat-orion/include
3 3
4obj-y += system-controller.o 4obj-y += system-controller.o
5obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o 5obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o coherency.o coherency_ll.o pmsu.o
6obj-$(CONFIG_SMP) += platsmp.o headsmp.o
7obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-mvebu/addr-map.c b/arch/arm/mach-mvebu/addr-map.c
index fe454a4430be..ab9b3bd4fef5 100644
--- a/arch/arm/mach-mvebu/addr-map.c
+++ b/arch/arm/mach-mvebu/addr-map.c
@@ -78,7 +78,7 @@ armada_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
78 if (win < 8) 78 if (win < 8)
79 offset = (win << 4); 79 offset = (win << 4);
80 else 80 else
81 offset = ARMADA_WINDOW_8_PLUS_OFFSET + (win << 3); 81 offset = ARMADA_WINDOW_8_PLUS_OFFSET + ((win - 8) << 3);
82 82
83 return cfg->bridge_virt_base + offset; 83 return cfg->bridge_virt_base + offset;
84} 84}
@@ -108,6 +108,9 @@ static int __init armada_setup_cpu_mbus(void)
108 108
109 addr_map_cfg.bridge_virt_base = mbus_unit_addr_decoding_base; 109 addr_map_cfg.bridge_virt_base = mbus_unit_addr_decoding_base;
110 110
111 if (of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric"))
112 addr_map_cfg.hw_io_coherency = 1;
113
111 /* 114 /*
112 * Disable, clear and configure windows. 115 * Disable, clear and configure windows.
113 */ 116 */
diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c
index 49d791548ad6..7434b5e36197 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.c
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
@@ -17,11 +17,14 @@
17#include <linux/of_platform.h> 17#include <linux/of_platform.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/time-armada-370-xp.h> 19#include <linux/time-armada-370-xp.h>
20#include <linux/clk/mvebu.h>
21#include <linux/dma-mapping.h>
20#include <asm/mach/arch.h> 22#include <asm/mach/arch.h>
21#include <asm/mach/map.h> 23#include <asm/mach/map.h>
22#include <asm/mach/time.h> 24#include <asm/mach/time.h>
23#include "armada-370-xp.h" 25#include "armada-370-xp.h"
24#include "common.h" 26#include "common.h"
27#include "coherency.h"
25 28
26static struct map_desc armada_370_xp_io_desc[] __initdata = { 29static struct map_desc armada_370_xp_io_desc[] __initdata = {
27 { 30 {
@@ -37,27 +40,45 @@ void __init armada_370_xp_map_io(void)
37 iotable_init(armada_370_xp_io_desc, ARRAY_SIZE(armada_370_xp_io_desc)); 40 iotable_init(armada_370_xp_io_desc, ARRAY_SIZE(armada_370_xp_io_desc));
38} 41}
39 42
43void __init armada_370_xp_timer_and_clk_init(void)
44{
45 mvebu_clocks_init();
46 armada_370_xp_timer_init();
47}
48
49void __init armada_370_xp_init_early(void)
50{
51 /*
52 * Some Armada 370/XP devices allocate their coherent buffers
53 * from atomic context. Increase size of atomic coherent pool
54 * to make sure such the allocations won't fail.
55 */
56 init_dma_coherent_pool_size(SZ_1M);
57}
58
40struct sys_timer armada_370_xp_timer = { 59struct sys_timer armada_370_xp_timer = {
41 .init = armada_370_xp_timer_init, 60 .init = armada_370_xp_timer_and_clk_init,
42}; 61};
43 62
44static void __init armada_370_xp_dt_init(void) 63static void __init armada_370_xp_dt_init(void)
45{ 64{
46 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 65 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
66 coherency_init();
47} 67}
48 68
49static const char * const armada_370_xp_dt_board_dt_compat[] = { 69static const char * const armada_370_xp_dt_compat[] = {
50 "marvell,a370-db", 70 "marvell,armada-370-xp",
51 "marvell,axp-db",
52 NULL, 71 NULL,
53}; 72};
54 73
55DT_MACHINE_START(ARMADA_XP_DT, "Marvell Aramada 370/XP (Device Tree)") 74DT_MACHINE_START(ARMADA_XP_DT, "Marvell Armada 370/XP (Device Tree)")
75 .smp = smp_ops(armada_xp_smp_ops),
56 .init_machine = armada_370_xp_dt_init, 76 .init_machine = armada_370_xp_dt_init,
57 .map_io = armada_370_xp_map_io, 77 .map_io = armada_370_xp_map_io,
78 .init_early = armada_370_xp_init_early,
58 .init_irq = armada_370_xp_init_irq, 79 .init_irq = armada_370_xp_init_irq,
59 .handle_irq = armada_370_xp_handle_irq, 80 .handle_irq = armada_370_xp_handle_irq,
60 .timer = &armada_370_xp_timer, 81 .timer = &armada_370_xp_timer,
61 .restart = mvebu_restart, 82 .restart = mvebu_restart,
62 .dt_compat = armada_370_xp_dt_board_dt_compat, 83 .dt_compat = armada_370_xp_dt_compat,
63MACHINE_END 84MACHINE_END
diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h
index aac9bebc6b03..c6a7d74fddfe 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.h
+++ b/arch/arm/mach-mvebu/armada-370-xp.h
@@ -19,4 +19,11 @@
19#define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfeb00000) 19#define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfeb00000)
20#define ARMADA_370_XP_REGS_SIZE SZ_1M 20#define ARMADA_370_XP_REGS_SIZE SZ_1M
21 21
22#ifdef CONFIG_SMP
23#include <linux/cpumask.h>
24
25void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq);
26void armada_xp_mpic_smp_cpu_init(void);
27#endif
28
22#endif /* __MACH_ARMADA_370_XP_H */ 29#endif /* __MACH_ARMADA_370_XP_H */
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
new file mode 100644
index 000000000000..8278960066c3
--- /dev/null
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -0,0 +1,155 @@
1/*
2 * Coherency fabric (Aurora) support for Armada 370 and XP platforms.
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Yehuda Yitschak <yehuday@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 have a coherency fabric which is
15 * responsible for ensuring hardware coherency between all CPUs and between
16 * CPUs and I/O masters. This file initializes the coherency fabric and
17 * supplies basic routines for configuring and controlling hardware coherency
18 */
19
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/of_address.h>
23#include <linux/io.h>
24#include <linux/smp.h>
25#include <linux/dma-mapping.h>
26#include <linux/platform_device.h>
27#include <asm/smp_plat.h>
28#include "armada-370-xp.h"
29
30/*
31 * Some functions in this file are called very early during SMP
32 * initialization. At that time the device tree framework is not yet
33 * ready, and it is not possible to get the register address to
34 * ioremap it. That's why the pointer below is given with an initial
35 * value matching its virtual mapping
36 */
37static void __iomem *coherency_base = ARMADA_370_XP_REGS_VIRT_BASE + 0x20200;
38static void __iomem *coherency_cpu_base;
39
40/* Coherency fabric registers */
41#define COHERENCY_FABRIC_CFG_OFFSET 0x4
42
43#define IO_SYNC_BARRIER_CTL_OFFSET 0x0
44
45static struct of_device_id of_coherency_table[] = {
46 {.compatible = "marvell,coherency-fabric"},
47 { /* end of list */ },
48};
49
50#ifdef CONFIG_SMP
51int coherency_get_cpu_count(void)
52{
53 int reg, cnt;
54
55 reg = readl(coherency_base + COHERENCY_FABRIC_CFG_OFFSET);
56 cnt = (reg & 0xF) + 1;
57
58 return cnt;
59}
60#endif
61
62/* Function defined in coherency_ll.S */
63int ll_set_cpu_coherent(void __iomem *base_addr, unsigned int hw_cpu_id);
64
65int set_cpu_coherent(unsigned int hw_cpu_id, int smp_group_id)
66{
67 if (!coherency_base) {
68 pr_warn("Can't make CPU %d cache coherent.\n", hw_cpu_id);
69 pr_warn("Coherency fabric is not initialized\n");
70 return 1;
71 }
72
73 return ll_set_cpu_coherent(coherency_base, hw_cpu_id);
74}
75
76static inline void mvebu_hwcc_sync_io_barrier(void)
77{
78 writel(0x1, coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET);
79 while (readl(coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET) & 0x1);
80}
81
82static dma_addr_t mvebu_hwcc_dma_map_page(struct device *dev, struct page *page,
83 unsigned long offset, size_t size,
84 enum dma_data_direction dir,
85 struct dma_attrs *attrs)
86{
87 if (dir != DMA_TO_DEVICE)
88 mvebu_hwcc_sync_io_barrier();
89 return pfn_to_dma(dev, page_to_pfn(page)) + offset;
90}
91
92
93static void mvebu_hwcc_dma_unmap_page(struct device *dev, dma_addr_t dma_handle,
94 size_t size, enum dma_data_direction dir,
95 struct dma_attrs *attrs)
96{
97 if (dir != DMA_TO_DEVICE)
98 mvebu_hwcc_sync_io_barrier();
99}
100
101static void mvebu_hwcc_dma_sync(struct device *dev, dma_addr_t dma_handle,
102 size_t size, enum dma_data_direction dir)
103{
104 if (dir != DMA_TO_DEVICE)
105 mvebu_hwcc_sync_io_barrier();
106}
107
108static struct dma_map_ops mvebu_hwcc_dma_ops = {
109 .alloc = arm_dma_alloc,
110 .free = arm_dma_free,
111 .mmap = arm_dma_mmap,
112 .map_page = mvebu_hwcc_dma_map_page,
113 .unmap_page = mvebu_hwcc_dma_unmap_page,
114 .get_sgtable = arm_dma_get_sgtable,
115 .map_sg = arm_dma_map_sg,
116 .unmap_sg = arm_dma_unmap_sg,
117 .sync_single_for_cpu = mvebu_hwcc_dma_sync,
118 .sync_single_for_device = mvebu_hwcc_dma_sync,
119 .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu,
120 .sync_sg_for_device = arm_dma_sync_sg_for_device,
121 .set_dma_mask = arm_dma_set_mask,
122};
123
124static int mvebu_hwcc_platform_notifier(struct notifier_block *nb,
125 unsigned long event, void *__dev)
126{
127 struct device *dev = __dev;
128
129 if (event != BUS_NOTIFY_ADD_DEVICE)
130 return NOTIFY_DONE;
131 set_dma_ops(dev, &mvebu_hwcc_dma_ops);
132
133 return NOTIFY_OK;
134}
135
136static struct notifier_block mvebu_hwcc_platform_nb = {
137 .notifier_call = mvebu_hwcc_platform_notifier,
138};
139
140int __init coherency_init(void)
141{
142 struct device_node *np;
143
144 np = of_find_matching_node(NULL, of_coherency_table);
145 if (np) {
146 pr_info("Initializing Coherency fabric\n");
147 coherency_base = of_iomap(np, 0);
148 coherency_cpu_base = of_iomap(np, 1);
149 set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
150 bus_register_notifier(&platform_bus_type,
151 &mvebu_hwcc_platform_nb);
152 }
153
154 return 0;
155}
diff --git a/arch/arm/mach-mvebu/coherency.h b/arch/arm/mach-mvebu/coherency.h
new file mode 100644
index 000000000000..2f428137f6fe
--- /dev/null
+++ b/arch/arm/mach-mvebu/coherency.h
@@ -0,0 +1,24 @@
1/*
2 * arch/arm/mach-mvebu/include/mach/coherency.h
3 *
4 *
5 * Coherency fabric (Aurora) support for Armada 370 and XP platforms.
6 *
7 * Copyright (C) 2012 Marvell
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#ifndef __MACH_370_XP_COHERENCY_H
15#define __MACH_370_XP_COHERENCY_H
16
17#ifdef CONFIG_SMP
18int coherency_get_cpu_count(void);
19#endif
20
21int set_cpu_coherent(int cpu_id, int smp_group_id);
22int coherency_init(void);
23
24#endif /* __MACH_370_XP_COHERENCY_H */
diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S
new file mode 100644
index 000000000000..53e8391192cd
--- /dev/null
+++ b/arch/arm/mach-mvebu/coherency_ll.S
@@ -0,0 +1,49 @@
1/*
2 * Coherency fabric: low level functions
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Gregory CLEMENT <gregory.clement@free-electrons.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 * This file implements the assembly function to add a CPU to the
13 * coherency fabric. This function is called by each of the secondary
14 * CPUs during their early boot in an SMP kernel, this why this
15 * function have to callable from assembly. It can also be called by a
16 * primary CPU from C code during its boot.
17 */
18
19#include <linux/linkage.h>
20#define ARMADA_XP_CFB_CTL_REG_OFFSET 0x0
21#define ARMADA_XP_CFB_CFG_REG_OFFSET 0x4
22
23 .text
24/*
25 * r0: Coherency fabric base register address
26 * r1: HW CPU id
27 */
28ENTRY(ll_set_cpu_coherent)
29 /* Create bit by cpu index */
30 mov r3, #(1 << 24)
31 lsl r1, r3, r1
32
33 /* Add CPU to SMP group - Atomic */
34 add r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET
35 ldr r2, [r3]
36 orr r2, r2, r1
37 str r2, [r3]
38
39 /* Enable coherency on CPU - Atomic */
40 add r3, r0, #ARMADA_XP_CFB_CFG_REG_OFFSET
41 ldr r2, [r3]
42 orr r2, r2, r1
43 str r2, [r3]
44
45 dsb
46
47 mov r0, #0
48 mov pc, lr
49ENDPROC(ll_set_cpu_coherent)
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
index 02f89eaa25fe..aa27bc2ffb60 100644
--- a/arch/arm/mach-mvebu/common.h
+++ b/arch/arm/mach-mvebu/common.h
@@ -20,4 +20,9 @@ void mvebu_restart(char mode, const char *cmd);
20void armada_370_xp_init_irq(void); 20void armada_370_xp_init_irq(void);
21void armada_370_xp_handle_irq(struct pt_regs *regs); 21void armada_370_xp_handle_irq(struct pt_regs *regs);
22 22
23void armada_xp_cpu_die(unsigned int cpu);
24int armada_370_xp_coherency_init(void);
25int armada_370_xp_pmsu_init(void);
26void armada_xp_secondary_startup(void);
27extern struct smp_operations armada_xp_smp_ops;
23#endif 28#endif
diff --git a/arch/arm/mach-mvebu/headsmp.S b/arch/arm/mach-mvebu/headsmp.S
new file mode 100644
index 000000000000..a06e0ede8c08
--- /dev/null
+++ b/arch/arm/mach-mvebu/headsmp.S
@@ -0,0 +1,49 @@
1/*
2 * SMP support: Entry point for secondary CPUs
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Yehuda Yitschak <yehuday@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 * This file implements the assembly entry point for secondary CPUs in
15 * an SMP kernel. The only thing we need to do is to add the CPU to
16 * the coherency fabric by writing to 2 registers. Currently the base
17 * register addresses are hard coded due to the early initialisation
18 * problems.
19 */
20
21#include <linux/linkage.h>
22#include <linux/init.h>
23
24/*
25 * At this stage the secondary CPUs don't have acces yet to the MMU, so
26 * we have to provide physical addresses
27 */
28#define ARMADA_XP_CFB_BASE 0xD0020200
29
30 __CPUINIT
31
32/*
33 * Armada XP specific entry point for secondary CPUs.
34 * We add the CPU to the coherency fabric and then jump to secondary
35 * startup
36 */
37ENTRY(armada_xp_secondary_startup)
38
39 /* Read CPU id */
40 mrc p15, 0, r1, c0, c0, 5
41 and r1, r1, #0xF
42
43 /* Add CPU to coherency fabric */
44 ldr r0, =ARMADA_XP_CFB_BASE
45
46 bl ll_set_cpu_coherent
47 b secondary_startup
48
49ENDPROC(armada_xp_secondary_startup)
diff --git a/arch/arm/mach-mvebu/hotplug.c b/arch/arm/mach-mvebu/hotplug.c
new file mode 100644
index 000000000000..b228b6a80c85
--- /dev/null
+++ b/arch/arm/mach-mvebu/hotplug.c
@@ -0,0 +1,30 @@
1/*
2 * Symmetric Multi Processing (SMP) support for Armada XP
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#include <linux/kernel.h>
15#include <linux/errno.h>
16#include <linux/smp.h>
17#include <asm/proc-fns.h>
18
19/*
20 * platform-specific code to shutdown a CPU
21 *
22 * Called with IRQs disabled
23 */
24void __ref armada_xp_cpu_die(unsigned int cpu)
25{
26 cpu_do_idle();
27
28 /* We should never return from idle */
29 panic("mvebu: cpu %d unexpectedly exit from shutdown\n", cpu);
30}
diff --git a/arch/arm/mach-mvebu/irq-armada-370-xp.c b/arch/arm/mach-mvebu/irq-armada-370-xp.c
index 5f5f9394b6b2..8e3fb082c3c6 100644
--- a/arch/arm/mach-mvebu/irq-armada-370-xp.c
+++ b/arch/arm/mach-mvebu/irq-armada-370-xp.c
@@ -24,6 +24,8 @@
24#include <linux/irqdomain.h> 24#include <linux/irqdomain.h>
25#include <asm/mach/arch.h> 25#include <asm/mach/arch.h>
26#include <asm/exception.h> 26#include <asm/exception.h>
27#include <asm/smp_plat.h>
28#include <asm/hardware/cache-l2x0.h>
27 29
28/* Interrupt Controller Registers Map */ 30/* Interrupt Controller Registers Map */
29#define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48) 31#define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48)
@@ -35,6 +37,12 @@
35 37
36#define ARMADA_370_XP_CPU_INTACK_OFFS (0x44) 38#define ARMADA_370_XP_CPU_INTACK_OFFS (0x44)
37 39
40#define ARMADA_370_XP_SW_TRIG_INT_OFFS (0x4)
41#define ARMADA_370_XP_IN_DRBEL_MSK_OFFS (0xc)
42#define ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS (0x8)
43
44#define ACTIVE_DOORBELLS (8)
45
38static void __iomem *per_cpu_int_base; 46static void __iomem *per_cpu_int_base;
39static void __iomem *main_int_base; 47static void __iomem *main_int_base;
40static struct irq_domain *armada_370_xp_mpic_domain; 48static struct irq_domain *armada_370_xp_mpic_domain;
@@ -51,11 +59,22 @@ static void armada_370_xp_irq_unmask(struct irq_data *d)
51 per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); 59 per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
52} 60}
53 61
62#ifdef CONFIG_SMP
63static int armada_xp_set_affinity(struct irq_data *d,
64 const struct cpumask *mask_val, bool force)
65{
66 return 0;
67}
68#endif
69
54static struct irq_chip armada_370_xp_irq_chip = { 70static struct irq_chip armada_370_xp_irq_chip = {
55 .name = "armada_370_xp_irq", 71 .name = "armada_370_xp_irq",
56 .irq_mask = armada_370_xp_irq_mask, 72 .irq_mask = armada_370_xp_irq_mask,
57 .irq_mask_ack = armada_370_xp_irq_mask, 73 .irq_mask_ack = armada_370_xp_irq_mask,
58 .irq_unmask = armada_370_xp_irq_unmask, 74 .irq_unmask = armada_370_xp_irq_unmask,
75#ifdef CONFIG_SMP
76 .irq_set_affinity = armada_xp_set_affinity,
77#endif
59}; 78};
60 79
61static int armada_370_xp_mpic_irq_map(struct irq_domain *h, 80static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
@@ -72,6 +91,41 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
72 return 0; 91 return 0;
73} 92}
74 93
94#ifdef CONFIG_SMP
95void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq)
96{
97 int cpu;
98 unsigned long map = 0;
99
100 /* Convert our logical CPU mask into a physical one. */
101 for_each_cpu(cpu, mask)
102 map |= 1 << cpu_logical_map(cpu);
103
104 /*
105 * Ensure that stores to Normal memory are visible to the
106 * other CPUs before issuing the IPI.
107 */
108 dsb();
109
110 /* submit softirq */
111 writel((map << 8) | irq, main_int_base +
112 ARMADA_370_XP_SW_TRIG_INT_OFFS);
113}
114
115void armada_xp_mpic_smp_cpu_init(void)
116{
117 /* Clear pending IPIs */
118 writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
119
120 /* Enable first 8 IPIs */
121 writel((1 << ACTIVE_DOORBELLS) - 1, per_cpu_int_base +
122 ARMADA_370_XP_IN_DRBEL_MSK_OFFS);
123
124 /* Unmask IPI interrupt */
125 writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
126}
127#endif /* CONFIG_SMP */
128
75static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { 129static struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
76 .map = armada_370_xp_mpic_irq_map, 130 .map = armada_370_xp_mpic_irq_map,
77 .xlate = irq_domain_xlate_onecell, 131 .xlate = irq_domain_xlate_onecell,
@@ -91,13 +145,18 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
91 control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL); 145 control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL);
92 146
93 armada_370_xp_mpic_domain = 147 armada_370_xp_mpic_domain =
94 irq_domain_add_linear(node, (control >> 2) & 0x3ff, 148 irq_domain_add_linear(node, (control >> 2) & 0x3ff,
95 &armada_370_xp_mpic_irq_ops, NULL); 149 &armada_370_xp_mpic_irq_ops, NULL);
96 150
97 if (!armada_370_xp_mpic_domain) 151 if (!armada_370_xp_mpic_domain)
98 panic("Unable to add Armada_370_Xp MPIC irq domain (DT)\n"); 152 panic("Unable to add Armada_370_Xp MPIC irq domain (DT)\n");
99 153
100 irq_set_default_host(armada_370_xp_mpic_domain); 154 irq_set_default_host(armada_370_xp_mpic_domain);
155
156#ifdef CONFIG_SMP
157 armada_xp_mpic_smp_cpu_init();
158#endif
159
101 return 0; 160 return 0;
102} 161}
103 162
@@ -111,14 +170,36 @@ asmlinkage void __exception_irq_entry armada_370_xp_handle_irq(struct pt_regs
111 ARMADA_370_XP_CPU_INTACK_OFFS); 170 ARMADA_370_XP_CPU_INTACK_OFFS);
112 irqnr = irqstat & 0x3FF; 171 irqnr = irqstat & 0x3FF;
113 172
114 if (irqnr < 1023) { 173 if (irqnr > 1022)
115 irqnr = 174 break;
116 irq_find_mapping(armada_370_xp_mpic_domain, irqnr); 175
176 if (irqnr >= 8) {
177 irqnr = irq_find_mapping(armada_370_xp_mpic_domain,
178 irqnr);
117 handle_IRQ(irqnr, regs); 179 handle_IRQ(irqnr, regs);
118 continue; 180 continue;
119 } 181 }
182#ifdef CONFIG_SMP
183 /* IPI Handling */
184 if (irqnr == 0) {
185 u32 ipimask, ipinr;
186
187 ipimask = readl_relaxed(per_cpu_int_base +
188 ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS)
189 & 0xFF;
190
191 writel(0x0, per_cpu_int_base +
192 ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
193
194 /* Handle all pending doorbells */
195 for (ipinr = 0; ipinr < ACTIVE_DOORBELLS; ipinr++) {
196 if (ipimask & (0x1 << ipinr))
197 handle_IPI(ipinr, regs);
198 }
199 continue;
200 }
201#endif
120 202
121 break;
122 } while (1); 203 } while (1);
123} 204}
124 205
@@ -130,4 +211,7 @@ static const struct of_device_id mpic_of_match[] __initconst = {
130void __init armada_370_xp_init_irq(void) 211void __init armada_370_xp_init_irq(void)
131{ 212{
132 of_irq_init(mpic_of_match); 213 of_irq_init(mpic_of_match);
214#ifdef CONFIG_CACHE_L2X0
215 l2x0_of_init(0, ~0UL);
216#endif
133} 217}
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
new file mode 100644
index 000000000000..fe16aaf7c19c
--- /dev/null
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -0,0 +1,122 @@
1/*
2 * Symmetric Multi Processing (SMP) support for Armada XP
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Lior Amsalem <alior@marvell.com>
7 * Yehuda Yitschak <yehuday@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 * The Armada XP SoC has 4 ARMv7 PJ4B CPUs running in full HW coherency
16 * This file implements the routines for preparing the SMP infrastructure
17 * and waking up the secondary CPUs
18 */
19
20#include <linux/init.h>
21#include <linux/smp.h>
22#include <linux/clk.h>
23#include <linux/of.h>
24#include <asm/cacheflush.h>
25#include <asm/smp_plat.h>
26#include "common.h"
27#include "armada-370-xp.h"
28#include "pmsu.h"
29#include "coherency.h"
30
31void __init set_secondary_cpus_clock(void)
32{
33 int thiscpu;
34 unsigned long rate;
35 struct clk *cpu_clk = NULL;
36 struct device_node *np = NULL;
37
38 thiscpu = smp_processor_id();
39 for_each_node_by_type(np, "cpu") {
40 int err;
41 int cpu;
42
43 err = of_property_read_u32(np, "reg", &cpu);
44 if (WARN_ON(err))
45 return;
46
47 if (cpu == thiscpu) {
48 cpu_clk = of_clk_get(np, 0);
49 break;
50 }
51 }
52 if (WARN_ON(IS_ERR(cpu_clk)))
53 return;
54 clk_prepare_enable(cpu_clk);
55 rate = clk_get_rate(cpu_clk);
56
57 /* set all the other CPU clk to the same rate than the boot CPU */
58 for_each_node_by_type(np, "cpu") {
59 int err;
60 int cpu;
61
62 err = of_property_read_u32(np, "reg", &cpu);
63 if (WARN_ON(err))
64 return;
65
66 if (cpu != thiscpu) {
67 cpu_clk = of_clk_get(np, 0);
68 clk_set_rate(cpu_clk, rate);
69 }
70 }
71}
72
73static void __cpuinit armada_xp_secondary_init(unsigned int cpu)
74{
75 armada_xp_mpic_smp_cpu_init();
76}
77
78static int __cpuinit armada_xp_boot_secondary(unsigned int cpu,
79 struct task_struct *idle)
80{
81 pr_info("Booting CPU %d\n", cpu);
82
83 armada_xp_boot_cpu(cpu, armada_xp_secondary_startup);
84
85 return 0;
86}
87
88static void __init armada_xp_smp_init_cpus(void)
89{
90 unsigned int i, ncores;
91 ncores = coherency_get_cpu_count();
92
93 /* Limit possible CPUs to defconfig */
94 if (ncores > nr_cpu_ids) {
95 pr_warn("SMP: %d CPUs physically present. Only %d configured.",
96 ncores, nr_cpu_ids);
97 pr_warn("Clipping CPU count to %d\n", nr_cpu_ids);
98 ncores = nr_cpu_ids;
99 }
100
101 for (i = 0; i < ncores; i++)
102 set_cpu_possible(i, true);
103
104 set_smp_cross_call(armada_mpic_send_doorbell);
105}
106
107void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
108{
109 set_secondary_cpus_clock();
110 flush_cache_all();
111 set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
112}
113
114struct smp_operations armada_xp_smp_ops __initdata = {
115 .smp_init_cpus = armada_xp_smp_init_cpus,
116 .smp_prepare_cpus = armada_xp_smp_prepare_cpus,
117 .smp_secondary_init = armada_xp_secondary_init,
118 .smp_boot_secondary = armada_xp_boot_secondary,
119#ifdef CONFIG_HOTPLUG_CPU
120 .cpu_die = armada_xp_cpu_die,
121#endif
122};
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
new file mode 100644
index 000000000000..3cc4bef6401c
--- /dev/null
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -0,0 +1,75 @@
1/*
2 * Power Management Service Unit(PMSU) support for Armada 370/XP platforms.
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Yehuda Yitschak <yehuday@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 have a power management service
15 * unit which is responsible for powering down and waking up CPUs and
16 * other SOC units
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/of_address.h>
22#include <linux/io.h>
23#include <linux/smp.h>
24#include <asm/smp_plat.h>
25
26static void __iomem *pmsu_mp_base;
27static void __iomem *pmsu_reset_base;
28
29#define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu) ((cpu * 0x100) + 0x24)
30#define PMSU_RESET_CTL_OFFSET(cpu) (cpu * 0x8)
31
32static struct of_device_id of_pmsu_table[] = {
33 {.compatible = "marvell,armada-370-xp-pmsu"},
34 { /* end of list */ },
35};
36
37#ifdef CONFIG_SMP
38int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr)
39{
40 int reg, hw_cpu;
41
42 if (!pmsu_mp_base || !pmsu_reset_base) {
43 pr_warn("Can't boot CPU. PMSU is uninitialized\n");
44 return 1;
45 }
46
47 hw_cpu = cpu_logical_map(cpu_id);
48
49 writel(virt_to_phys(boot_addr), pmsu_mp_base +
50 PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
51
52 /* Release CPU from reset by clearing reset bit*/
53 reg = readl(pmsu_reset_base + PMSU_RESET_CTL_OFFSET(hw_cpu));
54 reg &= (~0x1);
55 writel(reg, pmsu_reset_base + PMSU_RESET_CTL_OFFSET(hw_cpu));
56
57 return 0;
58}
59#endif
60
61int __init armada_370_xp_pmsu_init(void)
62{
63 struct device_node *np;
64
65 np = of_find_matching_node(NULL, of_pmsu_table);
66 if (np) {
67 pr_info("Initializing Power Management Service Unit\n");
68 pmsu_mp_base = of_iomap(np, 0);
69 pmsu_reset_base = of_iomap(np, 1);
70 }
71
72 return 0;
73}
74
75early_initcall(armada_370_xp_pmsu_init);
diff --git a/arch/arm/mach-mvebu/pmsu.h b/arch/arm/mach-mvebu/pmsu.h
new file mode 100644
index 000000000000..07a737c6b95d
--- /dev/null
+++ b/arch/arm/mach-mvebu/pmsu.h
@@ -0,0 +1,16 @@
1/*
2 * Power Management Service Unit (PMSU) support for Armada 370/XP platforms.
3 *
4 * Copyright (C) 2012 Marvell
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#ifndef __MACH_MVEBU_PMSU_H
12#define __MACH_MVEBU_PMSU_H
13
14int armada_xp_boot_cpu(unsigned int cpu_id, void *phys_addr);
15
16#endif /* __MACH_370_XP_PMSU_H */
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 94186b6c685f..3fd629d5a513 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -352,6 +352,10 @@ config CPU_PJ4
352 select ARM_THUMBEE 352 select ARM_THUMBEE
353 select CPU_V7 353 select CPU_V7
354 354
355config CPU_PJ4B
356 bool
357 select CPU_V7
358
355# ARMv6 359# ARMv6
356config CPU_V6 360config CPU_V6
357 bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX 361 bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 58bc3e4d3bd0..5383bc018571 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -124,8 +124,6 @@ static void arm_dma_sync_single_for_device(struct device *dev,
124 __dma_page_cpu_to_dev(page, offset, size, dir); 124 __dma_page_cpu_to_dev(page, offset, size, dir);
125} 125}
126 126
127static int arm_dma_set_mask(struct device *dev, u64 dma_mask);
128
129struct dma_map_ops arm_dma_ops = { 127struct dma_map_ops arm_dma_ops = {
130 .alloc = arm_dma_alloc, 128 .alloc = arm_dma_alloc,
131 .free = arm_dma_free, 129 .free = arm_dma_free,
@@ -971,7 +969,7 @@ int dma_supported(struct device *dev, u64 mask)
971} 969}
972EXPORT_SYMBOL(dma_supported); 970EXPORT_SYMBOL(dma_supported);
973 971
974static int arm_dma_set_mask(struct device *dev, u64 dma_mask) 972int arm_dma_set_mask(struct device *dev, u64 dma_mask)
975{ 973{
976 if (!dev->dma_mask || !dma_supported(dev, dma_mask)) 974 if (!dev->dma_mask || !dma_supported(dev, dma_mask))
977 return -EIO; 975 return -EIO;
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 42cc833aa02f..350f6a74992b 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -169,6 +169,63 @@ __v7_ca15mp_setup:
169 orreq r0, r0, r10 @ Enable CPU-specific SMP bits 169 orreq r0, r0, r10 @ Enable CPU-specific SMP bits
170 mcreq p15, 0, r0, c1, c0, 1 170 mcreq p15, 0, r0, c1, c0, 1
171#endif 171#endif
172
173__v7_pj4b_setup:
174#ifdef CONFIG_CPU_PJ4B
175
176/* Auxiliary Debug Modes Control 1 Register */
177#define PJ4B_STATIC_BP (1 << 2) /* Enable Static BP */
178#define PJ4B_INTER_PARITY (1 << 8) /* Disable Internal Parity Handling */
179#define PJ4B_BCK_OFF_STREX (1 << 5) /* Enable the back off of STREX instr */
180#define PJ4B_CLEAN_LINE (1 << 16) /* Disable data transfer for clean line */
181
182/* Auxiliary Debug Modes Control 2 Register */
183#define PJ4B_FAST_LDR (1 << 23) /* Disable fast LDR */
184#define PJ4B_SNOOP_DATA (1 << 25) /* Do not interleave write and snoop data */
185#define PJ4B_CWF (1 << 27) /* Disable Critical Word First feature */
186#define PJ4B_OUTSDNG_NC (1 << 29) /* Disable outstanding non cacheable rqst */
187#define PJ4B_L1_REP_RR (1 << 30) /* L1 replacement - Strict round robin */
188#define PJ4B_AUX_DBG_CTRL2 (PJ4B_SNOOP_DATA | PJ4B_CWF |\
189 PJ4B_OUTSDNG_NC | PJ4B_L1_REP_RR)
190
191/* Auxiliary Functional Modes Control Register 0 */
192#define PJ4B_SMP_CFB (1 << 1) /* Set SMP mode. Join the coherency fabric */
193#define PJ4B_L1_PAR_CHK (1 << 2) /* Support L1 parity checking */
194#define PJ4B_BROADCAST_CACHE (1 << 8) /* Broadcast Cache and TLB maintenance */
195
196/* Auxiliary Debug Modes Control 0 Register */
197#define PJ4B_WFI_WFE (1 << 22) /* WFI/WFE - serve the DVM and back to idle */
198
199 /* Auxiliary Debug Modes Control 1 Register */
200 mrc p15, 1, r0, c15, c1, 1
201 orr r0, r0, #PJ4B_CLEAN_LINE
202 orr r0, r0, #PJ4B_BCK_OFF_STREX
203 orr r0, r0, #PJ4B_INTER_PARITY
204 bic r0, r0, #PJ4B_STATIC_BP
205 mcr p15, 1, r0, c15, c1, 1
206
207 /* Auxiliary Debug Modes Control 2 Register */
208 mrc p15, 1, r0, c15, c1, 2
209 bic r0, r0, #PJ4B_FAST_LDR
210 orr r0, r0, #PJ4B_AUX_DBG_CTRL2
211 mcr p15, 1, r0, c15, c1, 2
212
213 /* Auxiliary Functional Modes Control Register 0 */
214 mrc p15, 1, r0, c15, c2, 0
215#ifdef CONFIG_SMP
216 orr r0, r0, #PJ4B_SMP_CFB
217#endif
218 orr r0, r0, #PJ4B_L1_PAR_CHK
219 orr r0, r0, #PJ4B_BROADCAST_CACHE
220 mcr p15, 1, r0, c15, c2, 0
221
222 /* Auxiliary Debug Modes Control 0 Register */
223 mrc p15, 1, r0, c15, c1, 0
224 orr r0, r0, #PJ4B_WFI_WFE
225 mcr p15, 1, r0, c15, c1, 0
226
227#endif /* CONFIG_CPU_PJ4B */
228
172__v7_setup: 229__v7_setup:
173 adr r12, __v7_setup_stack @ the local stack 230 adr r12, __v7_setup_stack @ the local stack
174 stmia r12, {r0-r5, r7, r9, r11, lr} 231 stmia r12, {r0-r5, r7, r9, r11, lr}
@@ -342,6 +399,16 @@ __v7_ca9mp_proc_info:
342 .long 0xff0ffff0 399 .long 0xff0ffff0
343 __v7_proc __v7_ca9mp_setup 400 __v7_proc __v7_ca9mp_setup
344 .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info 401 .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info
402
403 /*
404 * Marvell PJ4B processor.
405 */
406 .type __v7_pj4b_proc_info, #object
407__v7_pj4b_proc_info:
408 .long 0x562f5840
409 .long 0xfffffff0
410 __v7_proc __v7_pj4b_setup
411 .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info
345#endif /* CONFIG_ARM_LPAE */ 412#endif /* CONFIG_ARM_LPAE */
346 413
347 /* 414 /*
diff --git a/arch/arm/plat-orion/addr-map.c b/arch/arm/plat-orion/addr-map.c
index a7b8060c293a..febe3862873c 100644
--- a/arch/arm/plat-orion/addr-map.c
+++ b/arch/arm/plat-orion/addr-map.c
@@ -42,6 +42,8 @@ EXPORT_SYMBOL_GPL(mv_mbus_dram_info);
42#define WIN_REMAP_LO_OFF 0x0008 42#define WIN_REMAP_LO_OFF 0x0008
43#define WIN_REMAP_HI_OFF 0x000c 43#define WIN_REMAP_HI_OFF 0x000c
44 44
45#define ATTR_HW_COHERENCY (0x1 << 4)
46
45/* 47/*
46 * Default implementation 48 * Default implementation
47 */ 49 */
@@ -163,6 +165,8 @@ void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
163 w = &orion_mbus_dram_info.cs[cs++]; 165 w = &orion_mbus_dram_info.cs[cs++];
164 w->cs_index = i; 166 w->cs_index = i;
165 w->mbus_attr = 0xf & ~(1 << i); 167 w->mbus_attr = 0xf & ~(1 << i);
168 if (cfg->hw_io_coherency)
169 w->mbus_attr |= ATTR_HW_COHERENCY;
166 w->base = base & 0xffff0000; 170 w->base = base & 0xffff0000;
167 w->size = (size | 0x0000ffff) + 1; 171 w->size = (size | 0x0000ffff) + 1;
168 } 172 }
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
index b8a688cad4c2..2d4b6414609f 100644
--- a/arch/arm/plat-orion/common.c
+++ b/arch/arm/plat-orion/common.c
@@ -606,26 +606,6 @@ void __init orion_wdt_init(void)
606 ****************************************************************************/ 606 ****************************************************************************/
607static u64 orion_xor_dmamask = DMA_BIT_MASK(32); 607static u64 orion_xor_dmamask = DMA_BIT_MASK(32);
608 608
609void __init orion_xor_init_channels(
610 struct mv_xor_platform_data *orion_xor0_data,
611 struct platform_device *orion_xor0_channel,
612 struct mv_xor_platform_data *orion_xor1_data,
613 struct platform_device *orion_xor1_channel)
614{
615 /*
616 * two engines can't do memset simultaneously, this limitation
617 * satisfied by removing memset support from one of the engines.
618 */
619 dma_cap_set(DMA_MEMCPY, orion_xor0_data->cap_mask);
620 dma_cap_set(DMA_XOR, orion_xor0_data->cap_mask);
621 platform_device_register(orion_xor0_channel);
622
623 dma_cap_set(DMA_MEMCPY, orion_xor1_data->cap_mask);
624 dma_cap_set(DMA_MEMSET, orion_xor1_data->cap_mask);
625 dma_cap_set(DMA_XOR, orion_xor1_data->cap_mask);
626 platform_device_register(orion_xor1_channel);
627}
628
629/***************************************************************************** 609/*****************************************************************************
630 * XOR0 610 * XOR0
631 ****************************************************************************/ 611 ****************************************************************************/
@@ -636,61 +616,30 @@ static struct resource orion_xor0_shared_resources[] = {
636 }, { 616 }, {
637 .name = "xor 0 high", 617 .name = "xor 0 high",
638 .flags = IORESOURCE_MEM, 618 .flags = IORESOURCE_MEM,
619 }, {
620 .name = "irq channel 0",
621 .flags = IORESOURCE_IRQ,
622 }, {
623 .name = "irq channel 1",
624 .flags = IORESOURCE_IRQ,
639 }, 625 },
640}; 626};
641 627
642static struct platform_device orion_xor0_shared = { 628static struct mv_xor_channel_data orion_xor0_channels_data[2];
643 .name = MV_XOR_SHARED_NAME,
644 .id = 0,
645 .num_resources = ARRAY_SIZE(orion_xor0_shared_resources),
646 .resource = orion_xor0_shared_resources,
647};
648 629
649static struct resource orion_xor00_resources[] = { 630static struct mv_xor_platform_data orion_xor0_pdata = {
650 [0] = { 631 .channels = orion_xor0_channels_data,
651 .flags = IORESOURCE_IRQ,
652 },
653};
654
655static struct mv_xor_platform_data orion_xor00_data = {
656 .shared = &orion_xor0_shared,
657 .hw_id = 0,
658 .pool_size = PAGE_SIZE,
659}; 632};
660 633
661static struct platform_device orion_xor00_channel = { 634static struct platform_device orion_xor0_shared = {
662 .name = MV_XOR_NAME, 635 .name = MV_XOR_NAME,
663 .id = 0, 636 .id = 0,
664 .num_resources = ARRAY_SIZE(orion_xor00_resources), 637 .num_resources = ARRAY_SIZE(orion_xor0_shared_resources),
665 .resource = orion_xor00_resources, 638 .resource = orion_xor0_shared_resources,
666 .dev = { 639 .dev = {
667 .dma_mask = &orion_xor_dmamask, 640 .dma_mask = &orion_xor_dmamask,
668 .coherent_dma_mask = DMA_BIT_MASK(64), 641 .coherent_dma_mask = DMA_BIT_MASK(64),
669 .platform_data = &orion_xor00_data, 642 .platform_data = &orion_xor0_pdata,
670 },
671};
672
673static struct resource orion_xor01_resources[] = {
674 [0] = {
675 .flags = IORESOURCE_IRQ,
676 },
677};
678
679static struct mv_xor_platform_data orion_xor01_data = {
680 .shared = &orion_xor0_shared,
681 .hw_id = 1,
682 .pool_size = PAGE_SIZE,
683};
684
685static struct platform_device orion_xor01_channel = {
686 .name = MV_XOR_NAME,
687 .id = 1,
688 .num_resources = ARRAY_SIZE(orion_xor01_resources),
689 .resource = orion_xor01_resources,
690 .dev = {
691 .dma_mask = &orion_xor_dmamask,
692 .coherent_dma_mask = DMA_BIT_MASK(64),
693 .platform_data = &orion_xor01_data,
694 }, 643 },
695}; 644};
696 645
@@ -704,15 +653,23 @@ void __init orion_xor0_init(unsigned long mapbase_low,
704 orion_xor0_shared_resources[1].start = mapbase_high; 653 orion_xor0_shared_resources[1].start = mapbase_high;
705 orion_xor0_shared_resources[1].end = mapbase_high + 0xff; 654 orion_xor0_shared_resources[1].end = mapbase_high + 0xff;
706 655
707 orion_xor00_resources[0].start = irq_0; 656 orion_xor0_shared_resources[2].start = irq_0;
708 orion_xor00_resources[0].end = irq_0; 657 orion_xor0_shared_resources[2].end = irq_0;
709 orion_xor01_resources[0].start = irq_1; 658 orion_xor0_shared_resources[3].start = irq_1;
710 orion_xor01_resources[0].end = irq_1; 659 orion_xor0_shared_resources[3].end = irq_1;
711 660
712 platform_device_register(&orion_xor0_shared); 661 /*
662 * two engines can't do memset simultaneously, this limitation
663 * satisfied by removing memset support from one of the engines.
664 */
665 dma_cap_set(DMA_MEMCPY, orion_xor0_channels_data[0].cap_mask);
666 dma_cap_set(DMA_XOR, orion_xor0_channels_data[0].cap_mask);
667
668 dma_cap_set(DMA_MEMSET, orion_xor0_channels_data[1].cap_mask);
669 dma_cap_set(DMA_MEMCPY, orion_xor0_channels_data[1].cap_mask);
670 dma_cap_set(DMA_XOR, orion_xor0_channels_data[1].cap_mask);
713 671
714 orion_xor_init_channels(&orion_xor00_data, &orion_xor00_channel, 672 platform_device_register(&orion_xor0_shared);
715 &orion_xor01_data, &orion_xor01_channel);
716} 673}
717 674
718/***************************************************************************** 675/*****************************************************************************
@@ -725,61 +682,30 @@ static struct resource orion_xor1_shared_resources[] = {
725 }, { 682 }, {
726 .name = "xor 1 high", 683 .name = "xor 1 high",
727 .flags = IORESOURCE_MEM, 684 .flags = IORESOURCE_MEM,
685 }, {
686 .name = "irq channel 0",
687 .flags = IORESOURCE_IRQ,
688 }, {
689 .name = "irq channel 1",
690 .flags = IORESOURCE_IRQ,
728 }, 691 },
729}; 692};
730 693
731static struct platform_device orion_xor1_shared = { 694static struct mv_xor_channel_data orion_xor1_channels_data[2];
732 .name = MV_XOR_SHARED_NAME,
733 .id = 1,
734 .num_resources = ARRAY_SIZE(orion_xor1_shared_resources),
735 .resource = orion_xor1_shared_resources,
736};
737
738static struct resource orion_xor10_resources[] = {
739 [0] = {
740 .flags = IORESOURCE_IRQ,
741 },
742};
743
744static struct mv_xor_platform_data orion_xor10_data = {
745 .shared = &orion_xor1_shared,
746 .hw_id = 0,
747 .pool_size = PAGE_SIZE,
748};
749
750static struct platform_device orion_xor10_channel = {
751 .name = MV_XOR_NAME,
752 .id = 2,
753 .num_resources = ARRAY_SIZE(orion_xor10_resources),
754 .resource = orion_xor10_resources,
755 .dev = {
756 .dma_mask = &orion_xor_dmamask,
757 .coherent_dma_mask = DMA_BIT_MASK(64),
758 .platform_data = &orion_xor10_data,
759 },
760};
761
762static struct resource orion_xor11_resources[] = {
763 [0] = {
764 .flags = IORESOURCE_IRQ,
765 },
766};
767 695
768static struct mv_xor_platform_data orion_xor11_data = { 696static struct mv_xor_platform_data orion_xor1_pdata = {
769 .shared = &orion_xor1_shared, 697 .channels = orion_xor1_channels_data,
770 .hw_id = 1,
771 .pool_size = PAGE_SIZE,
772}; 698};
773 699
774static struct platform_device orion_xor11_channel = { 700static struct platform_device orion_xor1_shared = {
775 .name = MV_XOR_NAME, 701 .name = MV_XOR_NAME,
776 .id = 3, 702 .id = 1,
777 .num_resources = ARRAY_SIZE(orion_xor11_resources), 703 .num_resources = ARRAY_SIZE(orion_xor1_shared_resources),
778 .resource = orion_xor11_resources, 704 .resource = orion_xor1_shared_resources,
779 .dev = { 705 .dev = {
780 .dma_mask = &orion_xor_dmamask, 706 .dma_mask = &orion_xor_dmamask,
781 .coherent_dma_mask = DMA_BIT_MASK(64), 707 .coherent_dma_mask = DMA_BIT_MASK(64),
782 .platform_data = &orion_xor11_data, 708 .platform_data = &orion_xor1_pdata,
783 }, 709 },
784}; 710};
785 711
@@ -793,15 +719,23 @@ void __init orion_xor1_init(unsigned long mapbase_low,
793 orion_xor1_shared_resources[1].start = mapbase_high; 719 orion_xor1_shared_resources[1].start = mapbase_high;
794 orion_xor1_shared_resources[1].end = mapbase_high + 0xff; 720 orion_xor1_shared_resources[1].end = mapbase_high + 0xff;
795 721
796 orion_xor10_resources[0].start = irq_0; 722 orion_xor1_shared_resources[2].start = irq_0;
797 orion_xor10_resources[0].end = irq_0; 723 orion_xor1_shared_resources[2].end = irq_0;
798 orion_xor11_resources[0].start = irq_1; 724 orion_xor1_shared_resources[3].start = irq_1;
799 orion_xor11_resources[0].end = irq_1; 725 orion_xor1_shared_resources[3].end = irq_1;
800 726
801 platform_device_register(&orion_xor1_shared); 727 /*
728 * two engines can't do memset simultaneously, this limitation
729 * satisfied by removing memset support from one of the engines.
730 */
731 dma_cap_set(DMA_MEMCPY, orion_xor1_channels_data[0].cap_mask);
732 dma_cap_set(DMA_XOR, orion_xor1_channels_data[0].cap_mask);
802 733
803 orion_xor_init_channels(&orion_xor10_data, &orion_xor10_channel, 734 dma_cap_set(DMA_MEMSET, orion_xor1_channels_data[1].cap_mask);
804 &orion_xor11_data, &orion_xor11_channel); 735 dma_cap_set(DMA_MEMCPY, orion_xor1_channels_data[1].cap_mask);
736 dma_cap_set(DMA_XOR, orion_xor1_channels_data[1].cap_mask);
737
738 platform_device_register(&orion_xor1_shared);
805} 739}
806 740
807/***************************************************************************** 741/*****************************************************************************
diff --git a/arch/arm/plat-orion/include/plat/addr-map.h b/arch/arm/plat-orion/include/plat/addr-map.h
index ec63e4a627d0..b76c06569fe5 100644
--- a/arch/arm/plat-orion/include/plat/addr-map.h
+++ b/arch/arm/plat-orion/include/plat/addr-map.h
@@ -17,6 +17,7 @@ struct orion_addr_map_cfg {
17 const int num_wins; /* Total number of windows */ 17 const int num_wins; /* Total number of windows */
18 const int remappable_wins; 18 const int remappable_wins;
19 void __iomem *bridge_virt_base; 19 void __iomem *bridge_virt_base;
20 int hw_io_coherency;
20 21
21 /* If NULL, the default cpu_win_can_remap will be used, using 22 /* If NULL, the default cpu_win_can_remap will be used, using
22 the value in remappable_wins */ 23 the value in remappable_wins */
diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h
index 6bbc3fe5f58e..e06fc5fefa14 100644
--- a/arch/arm/plat-orion/include/plat/common.h
+++ b/arch/arm/plat-orion/include/plat/common.h
@@ -12,6 +12,7 @@
12#include <linux/mv643xx_eth.h> 12#include <linux/mv643xx_eth.h>
13 13
14struct dsa_platform_data; 14struct dsa_platform_data;
15struct mv_sata_platform_data;
15 16
16void __init orion_uart0_init(void __iomem *membase, 17void __init orion_uart0_init(void __iomem *membase,
17 resource_size_t mapbase, 18 resource_size_t mapbase,