aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-07 14:02:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-07 14:02:18 -0400
commitfcba914542082b272f31c8e4c40000b88ed3208d (patch)
treefb28069bf571d93420daafd501b4e97f221d526c
parenta8c4b90e670be3b01e9395c7310639c8109fc77e (diff)
parent5c5f0421a8eea5bdaba9b9313c5bb4833aeb39cd (diff)
Merge tag 'soc-for-linus-3' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC platform updates (part 3) from Arnd Bergmann: "This is the third and smallest of the SoC specific updates. Changes include: - SMP support for the Xilinx zynq platform - Smaller imx changes - LPAE support for mvebu - Moving the orion5x, kirkwood, dove and mvebu platforms to a common "mbus" driver for their internal devices. It would be good to get feedback on the location of the "mbus" driver. Since this is used on multiple platforms may potentially get shared with other architectures (powerpc and arm64), it was moved to drivers/bus/. We expect other similar drivers to get moved to the same place in order to avoid creating more top-level directories under drivers/ or cluttering up the messy drivers/misc/ even more." * tag 'soc-for-linus-3' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (50 commits) ARM: imx: reset_controller may be disabled ARM: mvebu: Align the internal registers virtual base to support LPAE ARM: mvebu: Limit the DMA zone when LPAE is selected arm: plat-orion: remove addr-map code arm: mach-mv78xx0: convert to use the mvebu-mbus driver arm: mach-orion5x: convert to use mvebu-mbus driver arm: mach-dove: convert to use mvebu-mbus driver arm: mach-kirkwood: convert to use mvebu-mbus driver arm: mach-mvebu: convert to use mvebu-mbus driver ARM i.MX53: set CLK_SET_RATE_PARENT flag on the tve_ext_sel clock ARM i.MX53: tve_di clock is not part of the CCM, but of TVE ARM i.MX53: make tve_ext_sel propagate rate change to PLL ARM i.MX53: Remove unused tve_gate clkdev entry ARM i.MX5: Remove tve_sel clock from i.MX53 clock tree ARM: i.MX5: Add PATA and SRTC clocks ARM: imx: do not bring up unavailable cores ARM: imx: add initial imx6dl support ARM: imx1: mm: add call to mxc_device_init ARM: imx_v4_v5_defconfig: Add CONFIG_GPIO_SYSFS ARM: imx_v6_v7_defconfig: Select CONFIG_PERF_EVENTS ...
-rw-r--r--Documentation/devicetree/bindings/clock/imx5-clock.txt14
-rw-r--r--Documentation/devicetree/bindings/clock/imx6q-clock.txt3
-rw-r--r--Documentation/devicetree/bindings/reset/fsl,imx-src.txt49
-rw-r--r--Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt3
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/Kconfig.debug4
-rw-r--r--arch/arm/boot/dts/armada-370-xp.dtsi5
-rw-r--r--arch/arm/boot/dts/zynq-7000.dtsi7
-rw-r--r--arch/arm/configs/imx_v4_v5_defconfig1
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig1
-rw-r--r--arch/arm/include/debug/mvebu.S2
-rw-r--r--arch/arm/mach-dove/Makefile2
-rw-r--r--arch/arm/mach-dove/addr-map.c125
-rw-r--r--arch/arm/mach-dove/board-dt.c2
-rw-r--r--arch/arm/mach-dove/common.c39
-rw-r--r--arch/arm/mach-dove/common.h2
-rw-r--r--arch/arm/mach-dove/include/mach/dove.h5
-rw-r--r--arch/arm/mach-imx/Kconfig10
-rw-r--r--arch/arm/mach-imx/Makefile1
-rw-r--r--arch/arm/mach-imx/anatop.c103
-rw-r--r--arch/arm/mach-imx/clk-imx51-imx53.c75
-rw-r--r--arch/arm/mach-imx/clk-imx6q.c126
-rw-r--r--arch/arm/mach-imx/clk.h17
-rw-r--r--arch/arm/mach-imx/common.h10
-rw-r--r--arch/arm/mach-imx/gpc.c23
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c74
-rw-r--r--arch/arm/mach-imx/mm-imx1.c2
-rw-r--r--arch/arm/mach-imx/mxc.h11
-rw-r--r--arch/arm/mach-imx/platsmp.c4
-rw-r--r--arch/arm/mach-imx/pm-imx6q.c4
-rw-r--r--arch/arm/mach-imx/src.c66
-rw-r--r--arch/arm/mach-kirkwood/Makefile2
-rw-r--r--arch/arm/mach-kirkwood/addr-map.c91
-rw-r--r--arch/arm/mach-kirkwood/board-dt.c2
-rw-r--r--arch/arm/mach-kirkwood/common.c38
-rw-r--r--arch/arm/mach-kirkwood/common.h2
-rw-r--r--arch/arm/mach-kirkwood/include/mach/kirkwood.h7
-rw-r--r--arch/arm/mach-kirkwood/pcie.c1
-rw-r--r--arch/arm/mach-mv78xx0/Makefile2
-rw-r--r--arch/arm/mach-mv78xx0/addr-map.c93
-rw-r--r--arch/arm/mach-mv78xx0/common.c10
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/mv78xx0.h9
-rw-r--r--arch/arm/mach-mv78xx0/pcie.c21
-rw-r--r--arch/arm/mach-mvebu/Kconfig2
-rw-r--r--arch/arm/mach-mvebu/Makefile2
-rw-r--r--arch/arm/mach-mvebu/addr-map.c137
-rw-r--r--arch/arm/mach-mvebu/armada-370-xp.c18
-rw-r--r--arch/arm/mach-mvebu/armada-370-xp.h8
-rw-r--r--arch/arm/mach-mvebu/platsmp.c2
-rw-r--r--arch/arm/mach-orion5x/Makefile2
-rw-r--r--arch/arm/mach-orion5x/addr-map.c155
-rw-r--r--arch/arm/mach-orion5x/board-dt.c2
-rw-r--r--arch/arm/mach-orion5x/common.c49
-rw-r--r--arch/arm/mach-orion5x/common.h13
-rw-r--r--arch/arm/mach-orion5x/d2net-setup.c4
-rw-r--r--arch/arm/mach-orion5x/db88f5281-setup.c13
-rw-r--r--arch/arm/mach-orion5x/dns323-setup.c3
-rw-r--r--arch/arm/mach-orion5x/edmini_v2-setup.c4
-rw-r--r--arch/arm/mach-orion5x/include/mach/orion5x.h6
-rw-r--r--arch/arm/mach-orion5x/kurobox_pro-setup.c8
-rw-r--r--arch/arm/mach-orion5x/ls-chl-setup.c4
-rw-r--r--arch/arm/mach-orion5x/ls_hgl-setup.c4
-rw-r--r--arch/arm/mach-orion5x/lsmini-setup.c4
-rw-r--r--arch/arm/mach-orion5x/mss2-setup.c3
-rw-r--r--arch/arm/mach-orion5x/mv2120-setup.c3
-rw-r--r--arch/arm/mach-orion5x/net2big-setup.c4
-rw-r--r--arch/arm/mach-orion5x/pci.c7
-rw-r--r--arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c4
-rw-r--r--arch/arm/mach-orion5x/rd88f5181l-ge-setup.c4
-rw-r--r--arch/arm/mach-orion5x/rd88f5182-setup.c7
-rw-r--r--arch/arm/mach-orion5x/terastation_pro2-setup.c4
-rw-r--r--arch/arm/mach-orion5x/ts209-setup.c4
-rw-r--r--arch/arm/mach-orion5x/ts409-setup.c4
-rw-r--r--arch/arm/mach-orion5x/wnr854t-setup.c4
-rw-r--r--arch/arm/mach-orion5x/wrt350n-v2-setup.c4
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7779.c23
-rw-r--r--arch/arm/mach-shmobile/include/mach/r8a7779.h2
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7779.c23
-rw-r--r--arch/arm/mach-zynq/Kconfig1
-rw-r--r--arch/arm/mach-zynq/Makefile6
-rw-r--r--arch/arm/mach-zynq/common.c67
-rw-r--r--arch/arm/mach-zynq/common.h20
-rw-r--r--arch/arm/mach-zynq/headsmp.S24
-rw-r--r--arch/arm/mach-zynq/hotplug.c104
-rw-r--r--arch/arm/mach-zynq/platsmp.c136
-rw-r--r--arch/arm/mach-zynq/slcr.c125
-rw-r--r--arch/arm/plat-orion/Makefile6
-rw-r--r--arch/arm/plat-orion/addr-map.c178
-rw-r--r--arch/arm/plat-orion/gpio.c59
-rw-r--r--drivers/bus/Kconfig7
-rw-r--r--drivers/bus/Makefile1
-rw-r--r--drivers/bus/mvebu-mbus.c870
-rw-r--r--drivers/pinctrl/sh-pfc/pfc-r8a7779.c2
-rw-r--r--drivers/staging/imx-drm/ipu-v3/ipu-common.c12
-rw-r--r--include/linux/mbus.h27
95 files changed, 2256 insertions, 1001 deletions
diff --git a/Documentation/devicetree/bindings/clock/imx5-clock.txt b/Documentation/devicetree/bindings/clock/imx5-clock.txt
index 2a0c904c46ae..d71b4b2c077d 100644
--- a/Documentation/devicetree/bindings/clock/imx5-clock.txt
+++ b/Documentation/devicetree/bindings/clock/imx5-clock.txt
@@ -38,7 +38,6 @@ clocks and IDs.
38 usb_phy_podf 23 38 usb_phy_podf 23
39 cpu_podf 24 39 cpu_podf 24
40 di_pred 25 40 di_pred 25
41 tve_di 26
42 tve_s 27 41 tve_s 27
43 uart1_ipg_gate 28 42 uart1_ipg_gate 28
44 uart1_per_gate 29 43 uart1_per_gate 29
@@ -172,6 +171,19 @@ clocks and IDs.
172 can1_serial_gate 157 171 can1_serial_gate 157
173 can1_ipg_gate 158 172 can1_ipg_gate 158
174 owire_gate 159 173 owire_gate 159
174 gpu3d_s 160
175 gpu2d_s 161
176 gpu3d_gate 162
177 gpu2d_gate 163
178 garb_gate 164
179 cko1_sel 165
180 cko1_podf 166
181 cko1 167
182 cko2_sel 168
183 cko2_podf 169
184 cko2 170
185 srtc_gate 171
186 pata_gate 172
175 187
176Examples (for mx53): 188Examples (for mx53):
177 189
diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt
index 969b38e06ad3..6deb6fd1c7cd 100644
--- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt
+++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt
@@ -205,6 +205,9 @@ clocks and IDs.
205 enet_ref 190 205 enet_ref 190
206 usbphy1_gate 191 206 usbphy1_gate 191
207 usbphy2_gate 192 207 usbphy2_gate 192
208 pll4_post_div 193
209 pll5_post_div 194
210 pll5_video_div 195
208 211
209Examples: 212Examples:
210 213
diff --git a/Documentation/devicetree/bindings/reset/fsl,imx-src.txt b/Documentation/devicetree/bindings/reset/fsl,imx-src.txt
new file mode 100644
index 000000000000..13301777e11c
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/fsl,imx-src.txt
@@ -0,0 +1,49 @@
1Freescale i.MX System Reset Controller
2======================================
3
4Please also refer to reset.txt in this directory for common reset
5controller binding usage.
6
7Required properties:
8- compatible: Should be "fsl,<chip>-src"
9- reg: should be register base and length as documented in the
10 datasheet
11- interrupts: Should contain SRC interrupt and CPU WDOG interrupt,
12 in this order.
13- #reset-cells: 1, see below
14
15example:
16
17src: src@020d8000 {
18 compatible = "fsl,imx6q-src";
19 reg = <0x020d8000 0x4000>;
20 interrupts = <0 91 0x04 0 96 0x04>;
21 #reset-cells = <1>;
22};
23
24Specifying reset lines connected to IP modules
25==============================================
26
27The system reset controller can be used to reset the GPU, VPU,
28IPU, and OpenVG IP modules on i.MX5 and i.MX6 ICs. Those device
29nodes should specify the reset line on the SRC in their resets
30property, containing a phandle to the SRC device node and a
31RESET_INDEX specifying which module to reset, as described in
32reset.txt
33
34example:
35
36 ipu1: ipu@02400000 {
37 resets = <&src 2>;
38 };
39 ipu2: ipu@02800000 {
40 resets = <&src 4>;
41 };
42
43The following RESET_INDEX values are valid for i.MX5:
44GPU_RESET 0
45VPU_RESET 1
46IPU1_RESET 2
47OPEN_VG_RESET 3
48The following additional RESET_INDEX value is valid for i.MX6:
49IPU2_RESET 4
diff --git a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
index 8071ac20d4b3..b876d4925a57 100644
--- a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
+++ b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
@@ -8,6 +8,8 @@ Required properties:
8- interrupts: Should contain sync interrupt and error interrupt, 8- interrupts: Should contain sync interrupt and error interrupt,
9 in this order. 9 in this order.
10- #crtc-cells: 1, See below 10- #crtc-cells: 1, See below
11- resets: phandle pointing to the system reset controller and
12 reset line index, see reset/fsl,imx-src.txt for details
11 13
12example: 14example:
13 15
@@ -16,6 +18,7 @@ ipu: ipu@18000000 {
16 compatible = "fsl,imx53-ipu"; 18 compatible = "fsl,imx53-ipu";
17 reg = <0x18000000 0x080000000>; 19 reg = <0x18000000 0x080000000>;
18 interrupts = <11 10>; 20 interrupts = <11 10>;
21 resets = <&src 2>;
19}; 22};
20 23
21Parallel display support 24Parallel display support
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5c56fa8824e9..18bef301d6e6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -498,6 +498,7 @@ config ARCH_DOVE
498 select PINCTRL_DOVE 498 select PINCTRL_DOVE
499 select PLAT_ORION_LEGACY 499 select PLAT_ORION_LEGACY
500 select USB_ARCH_HAS_EHCI 500 select USB_ARCH_HAS_EHCI
501 select MVEBU_MBUS
501 help 502 help
502 Support for the Marvell Dove SoC 88AP510 503 Support for the Marvell Dove SoC 88AP510
503 504
@@ -511,6 +512,7 @@ config ARCH_KIRKWOOD
511 select PINCTRL 512 select PINCTRL
512 select PINCTRL_KIRKWOOD 513 select PINCTRL_KIRKWOOD
513 select PLAT_ORION_LEGACY 514 select PLAT_ORION_LEGACY
515 select MVEBU_MBUS
514 help 516 help
515 Support for the following Marvell Kirkwood series SoCs: 517 Support for the following Marvell Kirkwood series SoCs:
516 88F6180, 88F6192 and 88F6281. 518 88F6180, 88F6192 and 88F6281.
@@ -522,6 +524,7 @@ config ARCH_MV78XX0
522 select GENERIC_CLOCKEVENTS 524 select GENERIC_CLOCKEVENTS
523 select PCI 525 select PCI
524 select PLAT_ORION_LEGACY 526 select PLAT_ORION_LEGACY
527 select MVEBU_MBUS
525 help 528 help
526 Support for the following Marvell MV78xx0 series SoCs: 529 Support for the following Marvell MV78xx0 series SoCs:
527 MV781x0, MV782x0. 530 MV781x0, MV782x0.
@@ -534,6 +537,7 @@ config ARCH_ORION5X
534 select GENERIC_CLOCKEVENTS 537 select GENERIC_CLOCKEVENTS
535 select PCI 538 select PCI
536 select PLAT_ORION_LEGACY 539 select PLAT_ORION_LEGACY
540 select MVEBU_MBUS
537 help 541 help
538 Support for the following Marvell Orion 5x series SoCs: 542 Support for the following Marvell Orion 5x series SoCs:
539 Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182), 543 Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index f57a6ba26e04..1d41908d5cda 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -245,11 +245,11 @@ choice
245 on i.MX53. 245 on i.MX53.
246 246
247 config DEBUG_IMX6Q_UART 247 config DEBUG_IMX6Q_UART
248 bool "i.MX6Q Debug UART" 248 bool "i.MX6Q/DL Debug UART"
249 depends on SOC_IMX6Q 249 depends on SOC_IMX6Q
250 help 250 help
251 Say Y here if you want kernel low-level debugging support 251 Say Y here if you want kernel low-level debugging support
252 on i.MX6Q. 252 on i.MX6Q/DL.
253 253
254 config DEBUG_MMP_UART2 254 config DEBUG_MMP_UART2
255 bool "Kernel low-level debugging message via MMP UART2" 255 bool "Kernel low-level debugging message via MMP UART2"
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 758c4ea90344..9693f796bcfe 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -73,11 +73,6 @@
73 clocks = <&coreclk 2>; 73 clocks = <&coreclk 2>;
74 }; 74 };
75 75
76 addr-decoding@d0020000 {
77 compatible = "marvell,armada-addr-decoding-controller";
78 reg = <0xd0020000 0x258>;
79 };
80
81 sata@d00a0000 { 76 sata@d00a0000 {
82 compatible = "marvell,orion-sata"; 77 compatible = "marvell,orion-sata";
83 reg = <0xd00a0000 0x2400>; 78 reg = <0xd00a0000 0x2400>;
diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi
index 748fc347ed18..14fb2e609bab 100644
--- a/arch/arm/boot/dts/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/zynq-7000.dtsi
@@ -136,5 +136,12 @@
136 clock-names = "cpu_1x"; 136 clock-names = "cpu_1x";
137 clock-ranges; 137 clock-ranges;
138 }; 138 };
139 scutimer: scutimer@f8f00600 {
140 interrupt-parent = <&intc>;
141 interrupts = < 1 13 0x301 >;
142 compatible = "arm,cortex-a9-twd-timer";
143 reg = < 0xf8f00600 0x20 >;
144 clocks = <&cpu_clk 1>;
145 } ;
139 }; 146 };
140}; 147};
diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig
index 02c657af4005..f07a847b00c9 100644
--- a/arch/arm/configs/imx_v4_v5_defconfig
+++ b/arch/arm/configs/imx_v4_v5_defconfig
@@ -109,6 +109,7 @@ CONFIG_I2C_IMX=y
109CONFIG_SPI=y 109CONFIG_SPI=y
110CONFIG_SPI_IMX=y 110CONFIG_SPI_IMX=y
111CONFIG_SPI_SPIDEV=y 111CONFIG_SPI_SPIDEV=y
112CONFIG_GPIO_SYSFS=y
112CONFIG_W1=y 113CONFIG_W1=y
113CONFIG_W1_MASTER_MXC=y 114CONFIG_W1_MASTER_MXC=y
114CONFIG_W1_SLAVE_THERM=y 115CONFIG_W1_SLAVE_THERM=y
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 088d6c11a0fa..6ec010f248b5 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -9,6 +9,7 @@ CONFIG_CGROUPS=y
9CONFIG_RELAY=y 9CONFIG_RELAY=y
10CONFIG_BLK_DEV_INITRD=y 10CONFIG_BLK_DEV_INITRD=y
11CONFIG_EXPERT=y 11CONFIG_EXPERT=y
12CONFIG_PERF_EVENTS=y
12# CONFIG_SLUB_DEBUG is not set 13# CONFIG_SLUB_DEBUG is not set
13# CONFIG_COMPAT_BRK is not set 14# CONFIG_COMPAT_BRK is not set
14CONFIG_MODULES=y 15CONFIG_MODULES=y
diff --git a/arch/arm/include/debug/mvebu.S b/arch/arm/include/debug/mvebu.S
index 865c6d02b332..df191afa3be1 100644
--- a/arch/arm/include/debug/mvebu.S
+++ b/arch/arm/include/debug/mvebu.S
@@ -12,7 +12,7 @@
12*/ 12*/
13 13
14#define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000 14#define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000
15#define ARMADA_370_XP_REGS_VIRT_BASE 0xfeb00000 15#define ARMADA_370_XP_REGS_VIRT_BASE 0xfec00000
16 16
17 .macro addruart, rp, rv, tmp 17 .macro addruart, rp, rv, tmp
18 ldr \rp, =ARMADA_370_XP_REGS_PHYS_BASE 18 ldr \rp, =ARMADA_370_XP_REGS_PHYS_BASE
diff --git a/arch/arm/mach-dove/Makefile b/arch/arm/mach-dove/Makefile
index 3f0a858fb597..4d9d2ffc4535 100644
--- a/arch/arm/mach-dove/Makefile
+++ b/arch/arm/mach-dove/Makefile
@@ -1,4 +1,4 @@
1obj-y += common.o addr-map.o irq.o 1obj-y += common.o irq.o
2obj-$(CONFIG_DOVE_LEGACY) += mpp.o 2obj-$(CONFIG_DOVE_LEGACY) += mpp.o
3obj-$(CONFIG_PCI) += pcie.o 3obj-$(CONFIG_PCI) += pcie.o
4obj-$(CONFIG_MACH_DOVE_DB) += dove-db-setup.o 4obj-$(CONFIG_MACH_DOVE_DB) += dove-db-setup.o
diff --git a/arch/arm/mach-dove/addr-map.c b/arch/arm/mach-dove/addr-map.c
deleted file mode 100644
index 2a06c0163418..000000000000
--- a/arch/arm/mach-dove/addr-map.c
+++ /dev/null
@@ -1,125 +0,0 @@
1/*
2 * arch/arm/mach-dove/addr-map.c
3 *
4 * Address map functions for Marvell Dove 88AP510 SoC
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/mbus.h>
14#include <linux/io.h>
15#include <asm/mach/arch.h>
16#include <asm/setup.h>
17#include <mach/dove.h>
18#include <plat/addr-map.h>
19#include "common.h"
20
21/*
22 * Generic Address Decode Windows bit settings
23 */
24#define TARGET_DDR 0x0
25#define TARGET_BOOTROM 0x1
26#define TARGET_CESA 0x3
27#define TARGET_PCIE0 0x4
28#define TARGET_PCIE1 0x8
29#define TARGET_SCRATCHPAD 0xd
30
31#define ATTR_CESA 0x01
32#define ATTR_BOOTROM 0xfd
33#define ATTR_DEV_SPI0_ROM 0xfe
34#define ATTR_DEV_SPI1_ROM 0xfb
35#define ATTR_PCIE_IO 0xe0
36#define ATTR_PCIE_MEM 0xe8
37#define ATTR_SCRATCHPAD 0x0
38
39static inline void __iomem *ddr_map_sc(int i)
40{
41 return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4));
42}
43
44/*
45 * Description of the windows needed by the platform code
46 */
47static struct __initdata orion_addr_map_cfg addr_map_cfg = {
48 .num_wins = 8,
49 .remappable_wins = 4,
50 .bridge_virt_base = BRIDGE_VIRT_BASE,
51};
52
53static const struct __initdata orion_addr_map_info addr_map_info[] = {
54 /*
55 * Windows for PCIe IO+MEM space.
56 */
57 { 0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE,
58 TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE
59 },
60 { 1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE,
61 TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE
62 },
63 { 2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE,
64 TARGET_PCIE0, ATTR_PCIE_MEM, -1
65 },
66 { 3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE,
67 TARGET_PCIE1, ATTR_PCIE_MEM, -1
68 },
69 /*
70 * Window for CESA engine.
71 */
72 { 4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE,
73 TARGET_CESA, ATTR_CESA, -1
74 },
75 /*
76 * Window to the BootROM for Standby and Sleep Resume
77 */
78 { 5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE,
79 TARGET_BOOTROM, ATTR_BOOTROM, -1
80 },
81 /*
82 * Window to the PMU Scratch Pad space
83 */
84 { 6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE,
85 TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1
86 },
87 /* End marker */
88 { -1, 0, 0, 0, 0, 0 }
89};
90
91void __init dove_setup_cpu_mbus(void)
92{
93 int i;
94 int cs;
95
96 /*
97 * Disable, clear and configure windows.
98 */
99 orion_config_wins(&addr_map_cfg, addr_map_info);
100
101 /*
102 * Setup MBUS dram target info.
103 */
104 orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
105
106 for (i = 0, cs = 0; i < 2; i++) {
107 u32 map = readl(ddr_map_sc(i));
108
109 /*
110 * Chip select enabled?
111 */
112 if (map & 1) {
113 struct mbus_dram_window *w;
114
115 w = &orion_mbus_dram_info.cs[cs++];
116 w->cs_index = i;
117 w->mbus_attr = 0; /* CS address decoding done inside */
118 /* the DDR controller, no need to */
119 /* provide attributes */
120 w->base = map & 0xff800000;
121 w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
122 }
123 }
124 orion_mbus_dram_info.num_cs = cs;
125}
diff --git a/arch/arm/mach-dove/board-dt.c b/arch/arm/mach-dove/board-dt.c
index fbde1dd67113..0b142803b2e1 100644
--- a/arch/arm/mach-dove/board-dt.c
+++ b/arch/arm/mach-dove/board-dt.c
@@ -64,7 +64,7 @@ static void __init dove_dt_init(void)
64#ifdef CONFIG_CACHE_TAUROS2 64#ifdef CONFIG_CACHE_TAUROS2
65 tauros2_init(0); 65 tauros2_init(0);
66#endif 66#endif
67 dove_setup_cpu_mbus(); 67 dove_setup_cpu_wins();
68 68
69 /* Setup root of clk tree */ 69 /* Setup root of clk tree */
70 dove_of_clk_init(); 70 dove_of_clk_init();
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
index c6b3b2bb50e7..e2b5da031f96 100644
--- a/arch/arm/mach-dove/common.c
+++ b/arch/arm/mach-dove/common.c
@@ -224,6 +224,9 @@ void __init dove_i2c_init(void)
224void __init dove_init_early(void) 224void __init dove_init_early(void)
225{ 225{
226 orion_time_set_base(TIMER_VIRT_BASE); 226 orion_time_set_base(TIMER_VIRT_BASE);
227 mvebu_mbus_init("marvell,dove-mbus",
228 BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
229 DOVE_MC_WINS_BASE, DOVE_MC_WINS_SZ);
227} 230}
228 231
229static int __init dove_find_tclk(void) 232static int __init dove_find_tclk(void)
@@ -326,6 +329,40 @@ void __init dove_sdio1_init(void)
326 platform_device_register(&dove_sdio1); 329 platform_device_register(&dove_sdio1);
327} 330}
328 331
332void __init dove_setup_cpu_wins(void)
333{
334 /*
335 * The PCIe windows will no longer be statically allocated
336 * here once Dove is migrated to the pci-mvebu driver.
337 */
338 mvebu_mbus_add_window_remap_flags("pcie0.0",
339 DOVE_PCIE0_IO_PHYS_BASE,
340 DOVE_PCIE0_IO_SIZE,
341 DOVE_PCIE0_IO_BUS_BASE,
342 MVEBU_MBUS_PCI_IO);
343 mvebu_mbus_add_window_remap_flags("pcie1.0",
344 DOVE_PCIE1_IO_PHYS_BASE,
345 DOVE_PCIE1_IO_SIZE,
346 DOVE_PCIE1_IO_BUS_BASE,
347 MVEBU_MBUS_PCI_IO);
348 mvebu_mbus_add_window_remap_flags("pcie0.0",
349 DOVE_PCIE0_MEM_PHYS_BASE,
350 DOVE_PCIE0_MEM_SIZE,
351 MVEBU_MBUS_NO_REMAP,
352 MVEBU_MBUS_PCI_MEM);
353 mvebu_mbus_add_window_remap_flags("pcie1.0",
354 DOVE_PCIE1_MEM_PHYS_BASE,
355 DOVE_PCIE1_MEM_SIZE,
356 MVEBU_MBUS_NO_REMAP,
357 MVEBU_MBUS_PCI_MEM);
358 mvebu_mbus_add_window("cesa", DOVE_CESA_PHYS_BASE,
359 DOVE_CESA_SIZE);
360 mvebu_mbus_add_window("bootrom", DOVE_BOOTROM_PHYS_BASE,
361 DOVE_BOOTROM_SIZE);
362 mvebu_mbus_add_window("scratchpad", DOVE_SCRATCHPAD_PHYS_BASE,
363 DOVE_SCRATCHPAD_SIZE);
364}
365
329void __init dove_init(void) 366void __init dove_init(void)
330{ 367{
331 pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n", 368 pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n",
@@ -334,7 +371,7 @@ void __init dove_init(void)
334#ifdef CONFIG_CACHE_TAUROS2 371#ifdef CONFIG_CACHE_TAUROS2
335 tauros2_init(0); 372 tauros2_init(0);
336#endif 373#endif
337 dove_setup_cpu_mbus(); 374 dove_setup_cpu_wins();
338 375
339 /* Setup root of clk tree */ 376 /* Setup root of clk tree */
340 dove_clk_init(); 377 dove_clk_init();
diff --git a/arch/arm/mach-dove/common.h b/arch/arm/mach-dove/common.h
index ee59fba4c6d1..e86347928b67 100644
--- a/arch/arm/mach-dove/common.h
+++ b/arch/arm/mach-dove/common.h
@@ -23,7 +23,7 @@ void dove_map_io(void);
23void dove_init(void); 23void dove_init(void);
24void dove_init_early(void); 24void dove_init_early(void);
25void dove_init_irq(void); 25void dove_init_irq(void);
26void dove_setup_cpu_mbus(void); 26void dove_setup_cpu_wins(void);
27void dove_ge00_init(struct mv643xx_eth_platform_data *eth_data); 27void dove_ge00_init(struct mv643xx_eth_platform_data *eth_data);
28void dove_sata_init(struct mv_sata_platform_data *sata_data); 28void dove_sata_init(struct mv_sata_platform_data *sata_data);
29#ifdef CONFIG_PCI 29#ifdef CONFIG_PCI
diff --git a/arch/arm/mach-dove/include/mach/dove.h b/arch/arm/mach-dove/include/mach/dove.h
index 661725e3115a..0c4b35f4ee5b 100644
--- a/arch/arm/mach-dove/include/mach/dove.h
+++ b/arch/arm/mach-dove/include/mach/dove.h
@@ -77,6 +77,8 @@
77/* North-South Bridge */ 77/* North-South Bridge */
78#define BRIDGE_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x20000) 78#define BRIDGE_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x20000)
79#define BRIDGE_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x20000) 79#define BRIDGE_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x20000)
80#define BRIDGE_WINS_BASE (BRIDGE_PHYS_BASE)
81#define BRIDGE_WINS_SZ (0x80)
80 82
81/* Cryptographic Engine */ 83/* Cryptographic Engine */
82#define DOVE_CRYPT_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x30000) 84#define DOVE_CRYPT_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x30000)
@@ -168,6 +170,9 @@
168#define DOVE_SSP_CLOCK_ENABLE (1 << 1) 170#define DOVE_SSP_CLOCK_ENABLE (1 << 1)
169#define DOVE_SSP_BPB_CLOCK_SRC_SSP (1 << 11) 171#define DOVE_SSP_BPB_CLOCK_SRC_SSP (1 << 11)
170/* Memory Controller */ 172/* Memory Controller */
173#define DOVE_MC_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE + 0x00000)
174#define DOVE_MC_WINS_BASE (DOVE_MC_PHYS_BASE + 0x100)
175#define DOVE_MC_WINS_SZ (0x8)
171#define DOVE_MC_VIRT_BASE (DOVE_NB_REGS_VIRT_BASE + 0x00000) 176#define DOVE_MC_VIRT_BASE (DOVE_NB_REGS_VIRT_BASE + 0x00000)
172 177
173/* LCD Controller */ 178/* LCD Controller */
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 2ebc97e16b91..78f795d73cb6 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -65,6 +65,9 @@ config IRAM_ALLOC
65 bool 65 bool
66 select GENERIC_ALLOCATOR 66 select GENERIC_ALLOCATOR
67 67
68config HAVE_IMX_ANATOP
69 bool
70
68config HAVE_IMX_GPC 71config HAVE_IMX_GPC
69 bool 72 bool
70 73
@@ -73,6 +76,7 @@ config HAVE_IMX_MMDC
73 76
74config HAVE_IMX_SRC 77config HAVE_IMX_SRC
75 def_bool y if SMP 78 def_bool y if SMP
79 select ARCH_HAS_RESET_CONTROLLER
76 80
77config IMX_HAVE_IOMUX_V1 81config IMX_HAVE_IOMUX_V1
78 bool 82 bool
@@ -115,6 +119,8 @@ config SOC_IMX25
115 119
116config SOC_IMX27 120config SOC_IMX27
117 bool 121 bool
122 select ARCH_HAS_CPUFREQ
123 select ARCH_HAS_OPP
118 select COMMON_CLK 124 select COMMON_CLK
119 select CPU_ARM926T 125 select CPU_ARM926T
120 select IMX_HAVE_IOMUX_V1 126 select IMX_HAVE_IOMUX_V1
@@ -142,6 +148,7 @@ config SOC_IMX35
142config SOC_IMX5 148config SOC_IMX5
143 bool 149 bool
144 select ARCH_HAS_CPUFREQ 150 select ARCH_HAS_CPUFREQ
151 select ARCH_HAS_OPP
145 select ARCH_MXC_IOMUX_V3 152 select ARCH_MXC_IOMUX_V3
146 select COMMON_CLK 153 select COMMON_CLK
147 select CPU_V7 154 select CPU_V7
@@ -783,7 +790,7 @@ config SOC_IMX53
783 This enables support for Freescale i.MX53 processor. 790 This enables support for Freescale i.MX53 processor.
784 791
785config SOC_IMX6Q 792config SOC_IMX6Q
786 bool "i.MX6 Quad support" 793 bool "i.MX6 Quad/DualLite support"
787 select ARCH_HAS_CPUFREQ 794 select ARCH_HAS_CPUFREQ
788 select ARCH_HAS_OPP 795 select ARCH_HAS_OPP
789 select ARM_CPU_SUSPEND if PM 796 select ARM_CPU_SUSPEND if PM
@@ -796,6 +803,7 @@ config SOC_IMX6Q
796 select HAVE_ARM_SCU if SMP 803 select HAVE_ARM_SCU if SMP
797 select HAVE_ARM_TWD if LOCAL_TIMERS 804 select HAVE_ARM_TWD if LOCAL_TIMERS
798 select HAVE_CAN_FLEXCAN if CAN 805 select HAVE_CAN_FLEXCAN if CAN
806 select HAVE_IMX_ANATOP
799 select HAVE_IMX_GPC 807 select HAVE_IMX_GPC
800 select HAVE_IMX_MMDC 808 select HAVE_IMX_MMDC
801 select HAVE_IMX_SRC 809 select HAVE_IMX_SRC
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index fbe60a145344..930958973f81 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -91,6 +91,7 @@ obj-$(CONFIG_MACH_EUKREA_CPUIMX35SD) += mach-cpuimx35.o
91obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o 91obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
92obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o 92obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
93 93
94obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o
94obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o 95obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
95obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o 96obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
96obj-$(CONFIG_HAVE_IMX_SRC) += src.o 97obj-$(CONFIG_HAVE_IMX_SRC) += src.o
diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c
new file mode 100644
index 000000000000..0cfa07dd9aa4
--- /dev/null
+++ b/arch/arm/mach-imx/anatop.c
@@ -0,0 +1,103 @@
1/*
2 * Copyright (C) 2013 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/err.h>
13#include <linux/io.h>
14#include <linux/of.h>
15#include <linux/of_address.h>
16#include <linux/mfd/syscon.h>
17#include <linux/regmap.h>
18#include "common.h"
19
20#define REG_SET 0x4
21#define REG_CLR 0x8
22
23#define ANADIG_REG_2P5 0x130
24#define ANADIG_REG_CORE 0x140
25#define ANADIG_ANA_MISC0 0x150
26#define ANADIG_USB1_CHRG_DETECT 0x1b0
27#define ANADIG_USB2_CHRG_DETECT 0x210
28#define ANADIG_DIGPROG 0x260
29
30#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000
31#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000
32#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000
33#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000
34#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000
35
36static struct regmap *anatop;
37
38static void imx_anatop_enable_weak2p5(bool enable)
39{
40 u32 reg, val;
41
42 regmap_read(anatop, ANADIG_ANA_MISC0, &val);
43
44 /* can only be enabled when stop_mode_config is clear. */
45 reg = ANADIG_REG_2P5;
46 reg += (enable && (val & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) ?
47 REG_SET : REG_CLR;
48 regmap_write(anatop, reg, BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG);
49}
50
51static void imx_anatop_enable_fet_odrive(bool enable)
52{
53 regmap_write(anatop, ANADIG_REG_CORE + (enable ? REG_SET : REG_CLR),
54 BM_ANADIG_REG_CORE_FET_ODRIVE);
55}
56
57void imx_anatop_pre_suspend(void)
58{
59 imx_anatop_enable_weak2p5(true);
60 imx_anatop_enable_fet_odrive(true);
61}
62
63void imx_anatop_post_resume(void)
64{
65 imx_anatop_enable_fet_odrive(false);
66 imx_anatop_enable_weak2p5(false);
67}
68
69void imx_anatop_usb_chrg_detect_disable(void)
70{
71 regmap_write(anatop, ANADIG_USB1_CHRG_DETECT,
72 BM_ANADIG_USB_CHRG_DETECT_EN_B
73 | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
74 regmap_write(anatop, ANADIG_USB2_CHRG_DETECT,
75 BM_ANADIG_USB_CHRG_DETECT_EN_B |
76 BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
77}
78
79u32 imx_anatop_get_digprog(void)
80{
81 struct device_node *np;
82 void __iomem *anatop_base;
83 static u32 digprog;
84
85 if (digprog)
86 return digprog;
87
88 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
89 anatop_base = of_iomap(np, 0);
90 WARN_ON(!anatop_base);
91 digprog = readl_relaxed(anatop_base + ANADIG_DIGPROG);
92
93 return digprog;
94}
95
96void __init imx_anatop_init(void)
97{
98 anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
99 if (IS_ERR(anatop)) {
100 pr_err("%s: failed to find imx6q-anatop regmap!\n", __func__);
101 return;
102 }
103}
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
index 2bc623b414c1..6fc486b6a3c6 100644
--- a/arch/arm/mach-imx/clk-imx51-imx53.c
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -45,16 +45,40 @@ static const char *mx53_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "
45static const char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", }; 45static const char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", };
46static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", }; 46static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", };
47static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", }; 47static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", };
48static const char *tve_sel[] = { "tve_pred", "tve_ext_sel", }; 48static const char *mx51_tve_sel[] = { "tve_pred", "tve_ext_sel", };
49static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; 49static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
50static const char *gpu3d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" };
51static const char *gpu2d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" };
50static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; 52static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
51static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", }; 53static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", };
54static const char *mx53_cko1_sel[] = {
55 "cpu_podf", "pll1_sw", "pll2_sw", "pll3_sw",
56 "emi_slow_podf", "pll4_sw", "nfc_podf", "dummy",
57 "di_pred", "dummy", "dummy", "ahb",
58 "ipg", "per_root", "ckil", "dummy",};
59static const char *mx53_cko2_sel[] = {
60 "dummy"/* dptc_core */, "dummy"/* dptc_perich */,
61 "dummy", "esdhc_a_podf",
62 "usboh3_podf", "dummy"/* wrck_clk_root */,
63 "ecspi_podf", "dummy"/* pll1_ref_clk */,
64 "esdhc_b_podf", "dummy"/* ddr_clk_root */,
65 "dummy"/* arm_axi_clk_root */, "dummy"/* usb_phy_out */,
66 "vpu_sel", "ipu_sel",
67 "osc", "ckih1",
68 "dummy", "esdhc_c_sel",
69 "ssi1_root_podf", "ssi2_root_podf",
70 "dummy", "dummy",
71 "dummy"/* lpsr_clk_root */, "dummy"/* pgc_clk_root */,
72 "dummy"/* tve_out */, "usb_phy_sel",
73 "tve_sel", "lp_apm",
74 "uart_root", "dummy"/* spdif0_clk_root */,
75 "dummy", "dummy", };
52 76
53enum imx5_clks { 77enum imx5_clks {
54 dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred, 78 dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred,
55 uart_root, esdhc_a_pred, esdhc_b_pred, esdhc_c_s, esdhc_d_s, 79 uart_root, esdhc_a_pred, esdhc_b_pred, esdhc_c_s, esdhc_d_s,
56 emi_sel, emi_slow_podf, nfc_podf, ecspi_pred, ecspi_podf, usboh3_pred, 80 emi_sel, emi_slow_podf, nfc_podf, ecspi_pred, ecspi_podf, usboh3_pred,
57 usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di, 81 usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di_unused,
58 tve_s, uart1_ipg_gate, uart1_per_gate, uart2_ipg_gate, 82 tve_s, uart1_ipg_gate, uart1_per_gate, uart2_ipg_gate,
59 uart2_per_gate, uart3_ipg_gate, uart3_per_gate, i2c1_gate, i2c2_gate, 83 uart2_per_gate, uart3_ipg_gate, uart3_per_gate, i2c1_gate, i2c2_gate,
60 gpt_ipg_gate, pwm1_ipg_gate, pwm1_hf_gate, pwm2_ipg_gate, pwm2_hf_gate, 84 gpt_ipg_gate, pwm1_ipg_gate, pwm1_hf_gate, pwm2_ipg_gate, pwm2_hf_gate,
@@ -83,7 +107,10 @@ enum imx5_clks {
83 ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate, 107 ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate,
84 epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate, 108 epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate,
85 can_sel, can1_serial_gate, can1_ipg_gate, 109 can_sel, can1_serial_gate, can1_ipg_gate,
86 owire_gate, 110 owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate,
111 cko1_sel, cko1_podf, cko1,
112 cko2_sel, cko2_podf, cko2,
113 srtc_gate, pata_gate,
87 clk_max 114 clk_max
88}; 115};
89 116
@@ -160,8 +187,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
160 usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str)); 187 usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
161 clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3); 188 clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3);
162 clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3); 189 clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3);
163 clk[tve_di] = imx_clk_fixed("tve_di", 65000000); /* FIXME */
164 clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, tve_sel, ARRAY_SIZE(tve_sel));
165 clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30); 190 clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30);
166 clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6); 191 clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6);
167 clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8); 192 clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8);
@@ -200,6 +225,11 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
200 clk[nfc_gate] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20); 225 clk[nfc_gate] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20);
201 clk[ipu_di0_gate] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10); 226 clk[ipu_di0_gate] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10);
202 clk[ipu_di1_gate] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12); 227 clk[ipu_di1_gate] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12);
228 clk[gpu3d_s] = imx_clk_mux("gpu3d_sel", MXC_CCM_CBCMR, 4, 2, gpu3d_sel, ARRAY_SIZE(gpu3d_sel));
229 clk[gpu2d_s] = imx_clk_mux("gpu2d_sel", MXC_CCM_CBCMR, 16, 2, gpu2d_sel, ARRAY_SIZE(gpu2d_sel));
230 clk[gpu3d_gate] = imx_clk_gate2("gpu3d_gate", "gpu3d_sel", MXC_CCM_CCGR5, 2);
231 clk[garb_gate] = imx_clk_gate2("garb_gate", "axi_a", MXC_CCM_CCGR5, 4);
232 clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "gpu2d_sel", MXC_CCM_CCGR6, 14);
203 clk[vpu_s] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel)); 233 clk[vpu_s] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel));
204 clk[vpu_gate] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6); 234 clk[vpu_gate] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6);
205 clk[vpu_reference_gate] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8); 235 clk[vpu_reference_gate] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8);
@@ -235,6 +265,8 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
235 clk[epit2_ipg_gate] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6); 265 clk[epit2_ipg_gate] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6);
236 clk[epit2_hf_gate] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8); 266 clk[epit2_hf_gate] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8);
237 clk[owire_gate] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22); 267 clk[owire_gate] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22);
268 clk[srtc_gate] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28);
269 clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0);
238 270
239 for (i = 0; i < ARRAY_SIZE(clk); i++) 271 for (i = 0; i < ARRAY_SIZE(clk); i++)
240 if (IS_ERR(clk[i])) 272 if (IS_ERR(clk[i]))
@@ -286,7 +318,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
286 clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0"); 318 clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0");
287 clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1"); 319 clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1");
288 clk_register_clkdev(clk[dummy], NULL, "imx-keypad"); 320 clk_register_clkdev(clk[dummy], NULL, "imx-keypad");
289 clk_register_clkdev(clk[tve_gate], NULL, "imx-tve.0");
290 clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0"); 321 clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0");
291 clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL); 322 clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL);
292 clk_register_clkdev(clk[epit1_ipg_gate], "ipg", "imx-epit.0"); 323 clk_register_clkdev(clk[epit1_ipg_gate], "ipg", "imx-epit.0");
@@ -331,8 +362,10 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
331 mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel)); 362 mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
332 clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, 363 clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
333 mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel)); 364 mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
334 clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, 365 clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
335 mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel)); 366 mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT);
367 clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1,
368 mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel));
336 clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30); 369 clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30);
337 clk[tve_pred] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3); 370 clk[tve_pred] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3);
338 clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); 371 clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
@@ -420,23 +453,23 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
420 clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE); 453 clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE);
421 clk[pll4_sw] = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE); 454 clk[pll4_sw] = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE);
422 455
423 clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1,
424 mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel));
425 clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); 456 clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
426 clk[ldb_di1_div] = imx_clk_divider("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1); 457 clk[ldb_di1_div] = imx_clk_divider_flags("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1, 0);
458 clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1,
459 mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel), CLK_SET_RATE_PARENT);
427 clk[di_pll4_podf] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3); 460 clk[di_pll4_podf] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3);
428 clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1,
429 mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel));
430 clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); 461 clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
431 clk[ldb_di0_div] = imx_clk_divider("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1); 462 clk[ldb_di0_div] = imx_clk_divider_flags("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1, 0);
463 clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1,
464 mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT);
432 clk[ldb_di0_gate] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28); 465 clk[ldb_di0_gate] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28);
433 clk[ldb_di1_gate] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30); 466 clk[ldb_di1_gate] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30);
434 clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, 467 clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
435 mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel)); 468 mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
436 clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, 469 clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
437 mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel)); 470 mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
438 clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, 471 clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
439 mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel)); 472 mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT);
440 clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30); 473 clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30);
441 clk[tve_pred] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3); 474 clk[tve_pred] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3);
442 clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); 475 clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
@@ -453,6 +486,16 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
453 clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6); 486 clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6);
454 clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22); 487 clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
455 488
489 clk[cko1_sel] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
490 mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
491 clk[cko1_podf] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3);
492 clk[cko1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7);
493
494 clk[cko2_sel] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5,
495 mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel));
496 clk[cko2_podf] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3);
497 clk[cko2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
498
456 for (i = 0; i < ARRAY_SIZE(clk); i++) 499 for (i = 0; i < ARRAY_SIZE(clk); i++)
457 if (IS_ERR(clk[i])) 500 if (IS_ERR(clk[i]))
458 pr_err("i.MX53 clk %d: register failed with %ld\n", 501 pr_err("i.MX53 clk %d: register failed with %ld\n",
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index d38e54f5b6d7..151259003086 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. 2 * Copyright 2011-2013 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd. 3 * Copyright 2011 Linaro Ltd.
4 * 4 *
5 * The code contained herein is licensed under the GNU General Public 5 * The code contained herein is licensed under the GNU General Public
@@ -14,6 +14,7 @@
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/clkdev.h> 16#include <linux/clkdev.h>
17#include <linux/delay.h>
17#include <linux/err.h> 18#include <linux/err.h>
18#include <linux/io.h> 19#include <linux/io.h>
19#include <linux/of.h> 20#include <linux/of.h>
@@ -22,6 +23,12 @@
22 23
23#include "clk.h" 24#include "clk.h"
24#include "common.h" 25#include "common.h"
26#include "hardware.h"
27
28#define CCR 0x0
29#define BM_CCR_WB_COUNT (0x7 << 16)
30#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21)
31#define BM_CCR_RBC_EN (0x1 << 27)
25 32
26#define CCGR0 0x68 33#define CCGR0 0x68
27#define CCGR1 0x6c 34#define CCGR1 0x6c
@@ -67,6 +74,67 @@ void imx6q_set_chicken_bit(void)
67 writel_relaxed(val, ccm_base + CGPR); 74 writel_relaxed(val, ccm_base + CGPR);
68} 75}
69 76
77static void imx6q_enable_rbc(bool enable)
78{
79 u32 val;
80 static bool last_rbc_mode;
81
82 if (last_rbc_mode == enable)
83 return;
84 /*
85 * need to mask all interrupts in GPC before
86 * operating RBC configurations
87 */
88 imx_gpc_mask_all();
89
90 /* configure RBC enable bit */
91 val = readl_relaxed(ccm_base + CCR);
92 val &= ~BM_CCR_RBC_EN;
93 val |= enable ? BM_CCR_RBC_EN : 0;
94 writel_relaxed(val, ccm_base + CCR);
95
96 /* configure RBC count */
97 val = readl_relaxed(ccm_base + CCR);
98 val &= ~BM_CCR_RBC_BYPASS_COUNT;
99 val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
100 writel(val, ccm_base + CCR);
101
102 /*
103 * need to delay at least 2 cycles of CKIL(32K)
104 * due to hardware design requirement, which is
105 * ~61us, here we use 65us for safe
106 */
107 udelay(65);
108
109 /* restore GPC interrupt mask settings */
110 imx_gpc_restore_all();
111
112 last_rbc_mode = enable;
113}
114
115static void imx6q_enable_wb(bool enable)
116{
117 u32 val;
118 static bool last_wb_mode;
119
120 if (last_wb_mode == enable)
121 return;
122
123 /* configure well bias enable bit */
124 val = readl_relaxed(ccm_base + CLPCR);
125 val &= ~BM_CLPCR_WB_PER_AT_LPM;
126 val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
127 writel_relaxed(val, ccm_base + CLPCR);
128
129 /* configure well bias count */
130 val = readl_relaxed(ccm_base + CCR);
131 val &= ~BM_CCR_WB_COUNT;
132 val |= enable ? BM_CCR_WB_COUNT : 0;
133 writel_relaxed(val, ccm_base + CCR);
134
135 last_wb_mode = enable;
136}
137
70int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) 138int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
71{ 139{
72 u32 val = readl_relaxed(ccm_base + CLPCR); 140 u32 val = readl_relaxed(ccm_base + CLPCR);
@@ -74,6 +142,8 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
74 val &= ~BM_CLPCR_LPM; 142 val &= ~BM_CLPCR_LPM;
75 switch (mode) { 143 switch (mode) {
76 case WAIT_CLOCKED: 144 case WAIT_CLOCKED:
145 imx6q_enable_wb(false);
146 imx6q_enable_rbc(false);
77 break; 147 break;
78 case WAIT_UNCLOCKED: 148 case WAIT_UNCLOCKED:
79 val |= 0x1 << BP_CLPCR_LPM; 149 val |= 0x1 << BP_CLPCR_LPM;
@@ -92,6 +162,8 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
92 val |= 0x3 << BP_CLPCR_STBY_COUNT; 162 val |= 0x3 << BP_CLPCR_STBY_COUNT;
93 val |= BM_CLPCR_VSTBY; 163 val |= BM_CLPCR_VSTBY;
94 val |= BM_CLPCR_SBYOS; 164 val |= BM_CLPCR_SBYOS;
165 imx6q_enable_wb(true);
166 imx6q_enable_rbc(true);
95 break; 167 break;
96 default: 168 default:
97 return -EINVAL; 169 return -EINVAL;
@@ -109,29 +181,29 @@ static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", };
109static const char *periph_sels[] = { "periph_pre", "periph_clk2", }; 181static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
110static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", }; 182static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
111static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", }; 183static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", };
112static const char *audio_sels[] = { "pll4_audio", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; 184static const char *audio_sels[] = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
113static const char *gpu_axi_sels[] = { "axi", "ahb", }; 185static const char *gpu_axi_sels[] = { "axi", "ahb", };
114static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", }; 186static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
115static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; 187static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
116static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; 188static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", };
117static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; 189static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
118static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", }; 190static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
119static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; 191static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
120static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; 192static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
121static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; 193static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
122static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; 194static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
123static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; 195static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
124static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", }; 196static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", };
125static const char *pcie_axi_sels[] = { "axi", "ahb", }; 197static const char *pcie_axi_sels[] = { "axi", "ahb", };
126static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio", }; 198static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_post_div", };
127static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; 199static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
128static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", }; 200static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", };
129static const char *emi_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", }; 201static const char *emi_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
130static const char *vdo_axi_sels[] = { "axi", "ahb", }; 202static const char *vdo_axi_sels[] = { "axi", "ahb", };
131static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", }; 203static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", };
132static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video", 204static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
133 "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", 205 "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0",
134 "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio", }; 206 "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_post_div", };
135 207
136enum mx6q_clks { 208enum mx6q_clks {
137 dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m, 209 dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m,
@@ -165,7 +237,7 @@ enum mx6q_clks {
165 pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg, 237 pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg,
166 ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5, 238 ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
167 sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate, 239 sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate,
168 usbphy2_gate, clk_max 240 usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, clk_max
169}; 241};
170 242
171static struct clk *clk[clk_max]; 243static struct clk *clk[clk_max];
@@ -182,6 +254,21 @@ static struct clk_div_table clk_enet_ref_table[] = {
182 { .val = 3, .div = 4, }, 254 { .val = 3, .div = 4, },
183}; 255};
184 256
257static struct clk_div_table post_div_table[] = {
258 { .val = 2, .div = 1, },
259 { .val = 1, .div = 2, },
260 { .val = 0, .div = 4, },
261 { }
262};
263
264static struct clk_div_table video_div_table[] = {
265 { .val = 0, .div = 1, },
266 { .val = 1, .div = 2, },
267 { .val = 2, .div = 1, },
268 { .val = 3, .div = 4, },
269 { }
270};
271
185int __init mx6q_clocks_init(void) 272int __init mx6q_clocks_init(void)
186{ 273{
187 struct device_node *np; 274 struct device_node *np;
@@ -208,6 +295,14 @@ int __init mx6q_clocks_init(void)
208 base = of_iomap(np, 0); 295 base = of_iomap(np, 0);
209 WARN_ON(!base); 296 WARN_ON(!base);
210 297
298 /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */
299 if (cpu_is_imx6q() && imx6q_revision() == IMX_CHIP_REVISION_1_0) {
300 post_div_table[1].div = 1;
301 post_div_table[2].div = 1;
302 video_div_table[1].div = 1;
303 video_div_table[2].div = 1;
304 };
305
211 /* type name parent_name base div_mask */ 306 /* type name parent_name base div_mask */
212 clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f); 307 clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f);
213 clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1); 308 clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1);
@@ -260,6 +355,10 @@ int __init mx6q_clocks_init(void)
260 clk[pll3_60m] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); 355 clk[pll3_60m] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
261 clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2); 356 clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2);
262 357
358 clk[pll4_post_div] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
359 clk[pll5_post_div] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
360 clk[pll5_video_div] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
361
263 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm"); 362 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm");
264 base = of_iomap(np, 0); 363 base = of_iomap(np, 0);
265 WARN_ON(!base); 364 WARN_ON(!base);
@@ -283,8 +382,8 @@ int __init mx6q_clocks_init(void)
283 clk[gpu3d_shader_sel] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); 382 clk[gpu3d_shader_sel] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
284 clk[ipu1_sel] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); 383 clk[ipu1_sel] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
285 clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); 384 clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
286 clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); 385 clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
287 clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); 386 clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
288 clk[ipu1_di0_pre_sel] = imx_clk_mux("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); 387 clk[ipu1_di0_pre_sel] = imx_clk_mux("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
289 clk[ipu1_di1_pre_sel] = imx_clk_mux("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); 388 clk[ipu1_di1_pre_sel] = imx_clk_mux("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
290 clk[ipu2_di0_pre_sel] = imx_clk_mux("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); 389 clk[ipu2_di0_pre_sel] = imx_clk_mux("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
@@ -332,9 +431,9 @@ int __init mx6q_clocks_init(void)
332 clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3); 431 clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3);
333 clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3); 432 clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3);
334 clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); 433 clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
335 clk[ldb_di0_podf] = imx_clk_divider("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1); 434 clk[ldb_di0_podf] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0);
336 clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); 435 clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
337 clk[ldb_di1_podf] = imx_clk_divider("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1); 436 clk[ldb_di1_podf] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0);
338 clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3); 437 clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3);
339 clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3); 438 clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3);
340 clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3); 439 clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3);
@@ -448,6 +547,11 @@ int __init mx6q_clocks_init(void)
448 clk_register_clkdev(clk[cko1], "cko1", NULL); 547 clk_register_clkdev(clk[cko1], "cko1", NULL);
449 clk_register_clkdev(clk[arm], NULL, "cpu0"); 548 clk_register_clkdev(clk[arm], NULL, "cpu0");
450 549
550 if (imx6q_revision() != IMX_CHIP_REVISION_1_0) {
551 clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
552 clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
553 }
554
451 /* 555 /*
452 * The gpmi needs 100MHz frequency in the EDO/Sync mode, 556 * The gpmi needs 100MHz frequency in the EDO/Sync mode,
453 * We can not get the 100MHz from the pll2_pfd0_352m. 557 * We can not get the 100MHz from the pll2_pfd0_352m.
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index 9d1f3b99d1d3..d9d9d9c66dff 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -59,6 +59,14 @@ static inline struct clk *imx_clk_divider(const char *name, const char *parent,
59 reg, shift, width, 0, &imx_ccm_lock); 59 reg, shift, width, 0, &imx_ccm_lock);
60} 60}
61 61
62static inline struct clk *imx_clk_divider_flags(const char *name,
63 const char *parent, void __iomem *reg, u8 shift, u8 width,
64 unsigned long flags)
65{
66 return clk_register_divider(NULL, name, parent, flags,
67 reg, shift, width, 0, &imx_ccm_lock);
68}
69
62static inline struct clk *imx_clk_gate(const char *name, const char *parent, 70static inline struct clk *imx_clk_gate(const char *name, const char *parent,
63 void __iomem *reg, u8 shift) 71 void __iomem *reg, u8 shift)
64{ 72{
@@ -73,6 +81,15 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
73 width, 0, &imx_ccm_lock); 81 width, 0, &imx_ccm_lock);
74} 82}
75 83
84static inline struct clk *imx_clk_mux_flags(const char *name,
85 void __iomem *reg, u8 shift, u8 width, const char **parents,
86 int num_parents, unsigned long flags)
87{
88 return clk_register_mux(NULL, name, parents, num_parents,
89 flags, reg, shift, width, 0,
90 &imx_ccm_lock);
91}
92
76static inline struct clk *imx_clk_fixed_factor(const char *name, 93static inline struct clk *imx_clk_fixed_factor(const char *name,
77 const char *parent, unsigned int mult, unsigned int div) 94 const char *parent, unsigned int mult, unsigned int div)
78{ 95{
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 9fea2522d7a3..4cba7dbb079f 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. 2 * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
3 */ 3 */
4 4
5/* 5/*
@@ -74,6 +74,7 @@ extern void mxc_set_cpu_type(unsigned int type);
74extern void mxc_restart(char, const char *); 74extern void mxc_restart(char, const char *);
75extern void mxc_arch_reset_init(void __iomem *); 75extern void mxc_arch_reset_init(void __iomem *);
76extern int mx53_revision(void); 76extern int mx53_revision(void);
77extern int imx6q_revision(void);
77extern int mx53_display_revision(void); 78extern int mx53_display_revision(void);
78extern void imx_set_aips(void __iomem *); 79extern void imx_set_aips(void __iomem *);
79extern int mxc_device_init(void); 80extern int mxc_device_init(void);
@@ -128,6 +129,13 @@ extern void imx_src_prepare_restart(void);
128extern void imx_gpc_init(void); 129extern void imx_gpc_init(void);
129extern void imx_gpc_pre_suspend(void); 130extern void imx_gpc_pre_suspend(void);
130extern void imx_gpc_post_resume(void); 131extern void imx_gpc_post_resume(void);
132extern void imx_gpc_mask_all(void);
133extern void imx_gpc_restore_all(void);
134extern void imx_anatop_init(void);
135extern void imx_anatop_pre_suspend(void);
136extern void imx_anatop_post_resume(void);
137extern void imx_anatop_usb_chrg_detect_disable(void);
138extern u32 imx_anatop_get_digprog(void);
131extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); 139extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
132extern void imx6q_set_chicken_bit(void); 140extern void imx6q_set_chicken_bit(void);
133 141
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 02b61cdf39b9..44a65e9ff1fc 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. 2 * Copyright 2011-2013 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd. 3 * Copyright 2011 Linaro Ltd.
4 * 4 *
5 * The code contained herein is licensed under the GNU General Public 5 * The code contained herein is licensed under the GNU General Public
@@ -69,6 +69,27 @@ static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on)
69 return 0; 69 return 0;
70} 70}
71 71
72void imx_gpc_mask_all(void)
73{
74 void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
75 int i;
76
77 for (i = 0; i < IMR_NUM; i++) {
78 gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
79 writel_relaxed(~0, reg_imr1 + i * 4);
80 }
81
82}
83
84void imx_gpc_restore_all(void)
85{
86 void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
87 int i;
88
89 for (i = 0; i < IMR_NUM; i++)
90 writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
91}
92
72static void imx_gpc_irq_unmask(struct irq_data *d) 93static void imx_gpc_irq_unmask(struct irq_data *d)
73{ 94{
74 void __iomem *reg; 95 void __iomem *reg;
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 99502eeefdf7..5536fd81379a 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. 2 * Copyright 2011-2013 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd. 3 * Copyright 2011 Linaro Ltd.
4 * 4 *
5 * The code contained herein is licensed under the GNU General Public 5 * The code contained herein is licensed under the GNU General Public
@@ -38,38 +38,32 @@
38#include "cpuidle.h" 38#include "cpuidle.h"
39#include "hardware.h" 39#include "hardware.h"
40 40
41#define IMX6Q_ANALOG_DIGPROG 0x260 41static u32 chip_revision;
42 42
43static int imx6q_revision(void) 43int imx6q_revision(void)
44{ 44{
45 struct device_node *np; 45 return chip_revision;
46 void __iomem *base; 46}
47 static u32 rev; 47
48 48static void __init imx6q_init_revision(void)
49 if (!rev) { 49{
50 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); 50 u32 rev = imx_anatop_get_digprog();
51 if (!np)
52 return IMX_CHIP_REVISION_UNKNOWN;
53 base = of_iomap(np, 0);
54 if (!base) {
55 of_node_put(np);
56 return IMX_CHIP_REVISION_UNKNOWN;
57 }
58 rev = readl_relaxed(base + IMX6Q_ANALOG_DIGPROG);
59 iounmap(base);
60 of_node_put(np);
61 }
62 51
63 switch (rev & 0xff) { 52 switch (rev & 0xff) {
64 case 0: 53 case 0:
65 return IMX_CHIP_REVISION_1_0; 54 chip_revision = IMX_CHIP_REVISION_1_0;
55 break;
66 case 1: 56 case 1:
67 return IMX_CHIP_REVISION_1_1; 57 chip_revision = IMX_CHIP_REVISION_1_1;
58 break;
68 case 2: 59 case 2:
69 return IMX_CHIP_REVISION_1_2; 60 chip_revision = IMX_CHIP_REVISION_1_2;
61 break;
70 default: 62 default:
71 return IMX_CHIP_REVISION_UNKNOWN; 63 chip_revision = IMX_CHIP_REVISION_UNKNOWN;
72 } 64 }
65
66 mxc_set_cpu_type(rev >> 16 & 0xff);
73} 67}
74 68
75static void imx6q_restart(char mode, const char *cmd) 69static void imx6q_restart(char mode, const char *cmd)
@@ -164,29 +158,7 @@ static void __init imx6q_1588_init(void)
164} 158}
165static void __init imx6q_usb_init(void) 159static void __init imx6q_usb_init(void)
166{ 160{
167 struct regmap *anatop; 161 imx_anatop_usb_chrg_detect_disable();
168
169#define HW_ANADIG_USB1_CHRG_DETECT 0x000001b0
170#define HW_ANADIG_USB2_CHRG_DETECT 0x00000210
171
172#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x00100000
173#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x00080000
174
175 anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
176 if (!IS_ERR(anatop)) {
177 /*
178 * The external charger detector needs to be disabled,
179 * or the signal at DP will be poor
180 */
181 regmap_write(anatop, HW_ANADIG_USB1_CHRG_DETECT,
182 BM_ANADIG_USB_CHRG_DETECT_EN_B
183 | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
184 regmap_write(anatop, HW_ANADIG_USB2_CHRG_DETECT,
185 BM_ANADIG_USB_CHRG_DETECT_EN_B |
186 BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
187 } else {
188 pr_warn("failed to find fsl,imx6q-anatop regmap\n");
189 }
190} 162}
191 163
192static void __init imx6q_init_machine(void) 164static void __init imx6q_init_machine(void)
@@ -196,6 +168,7 @@ static void __init imx6q_init_machine(void)
196 168
197 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 169 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
198 170
171 imx_anatop_init();
199 imx6q_pm_init(); 172 imx6q_pm_init();
200 imx6q_usb_init(); 173 imx6q_usb_init();
201 imx6q_1588_init(); 174 imx6q_1588_init();
@@ -282,6 +255,7 @@ static void __init imx6q_map_io(void)
282 255
283static void __init imx6q_init_irq(void) 256static void __init imx6q_init_irq(void)
284{ 257{
258 imx6q_init_revision();
285 l2x0_of_init(0, ~0UL); 259 l2x0_of_init(0, ~0UL);
286 imx_src_init(); 260 imx_src_init();
287 imx_gpc_init(); 261 imx_gpc_init();
@@ -292,15 +266,17 @@ static void __init imx6q_timer_init(void)
292{ 266{
293 mx6q_clocks_init(); 267 mx6q_clocks_init();
294 clocksource_of_init(); 268 clocksource_of_init();
295 imx_print_silicon_rev("i.MX6Q", imx6q_revision()); 269 imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
270 imx6q_revision());
296} 271}
297 272
298static const char *imx6q_dt_compat[] __initdata = { 273static const char *imx6q_dt_compat[] __initdata = {
274 "fsl,imx6dl",
299 "fsl,imx6q", 275 "fsl,imx6q",
300 NULL, 276 NULL,
301}; 277};
302 278
303DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)") 279DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
304 .smp = smp_ops(imx_smp_ops), 280 .smp = smp_ops(imx_smp_ops),
305 .map_io = imx6q_map_io, 281 .map_io = imx6q_map_io,
306 .init_irq = imx6q_init_irq, 282 .init_irq = imx6q_init_irq,
diff --git a/arch/arm/mach-imx/mm-imx1.c b/arch/arm/mach-imx/mm-imx1.c
index 7a146671e65a..3c609c52d3eb 100644
--- a/arch/arm/mach-imx/mm-imx1.c
+++ b/arch/arm/mach-imx/mm-imx1.c
@@ -51,6 +51,8 @@ void __init mx1_init_irq(void)
51 51
52void __init imx1_soc_init(void) 52void __init imx1_soc_init(void)
53{ 53{
54 mxc_device_init();
55
54 mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256, 56 mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256,
55 MX1_GPIO_INT_PORTA, 0); 57 MX1_GPIO_INT_PORTA, 0);
56 mxc_register_gpio("imx1-gpio", 1, MX1_GPIO2_BASE_ADDR, SZ_256, 58 mxc_register_gpio("imx1-gpio", 1, MX1_GPIO2_BASE_ADDR, SZ_256,
diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h
index 7dce17a9fe6c..8629e5be7ecd 100644
--- a/arch/arm/mach-imx/mxc.h
+++ b/arch/arm/mach-imx/mxc.h
@@ -34,6 +34,8 @@
34#define MXC_CPU_MX35 35 34#define MXC_CPU_MX35 35
35#define MXC_CPU_MX51 51 35#define MXC_CPU_MX51 51
36#define MXC_CPU_MX53 53 36#define MXC_CPU_MX53 53
37#define MXC_CPU_IMX6DL 0x61
38#define MXC_CPU_IMX6Q 0x63
37 39
38#define IMX_CHIP_REVISION_1_0 0x10 40#define IMX_CHIP_REVISION_1_0 0x10
39#define IMX_CHIP_REVISION_1_1 0x11 41#define IMX_CHIP_REVISION_1_1 0x11
@@ -150,6 +152,15 @@ extern unsigned int __mxc_cpu_type;
150#endif 152#endif
151 153
152#ifndef __ASSEMBLY__ 154#ifndef __ASSEMBLY__
155static inline bool cpu_is_imx6dl(void)
156{
157 return __mxc_cpu_type == MXC_CPU_IMX6DL;
158}
159
160static inline bool cpu_is_imx6q(void)
161{
162 return __mxc_cpu_type == MXC_CPU_IMX6Q;
163}
153 164
154struct cpu_op { 165struct cpu_op {
155 u32 cpu_rate; 166 u32 cpu_rate;
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
index 77e9a25ed0f6..4a69305db65e 100644
--- a/arch/arm/mach-imx/platsmp.c
+++ b/arch/arm/mach-imx/platsmp.c
@@ -68,8 +68,8 @@ static void __init imx_smp_init_cpus(void)
68 68
69 ncores = scu_get_core_count(scu_base); 69 ncores = scu_get_core_count(scu_base);
70 70
71 for (i = 0; i < ncores; i++) 71 for (i = ncores; i < NR_CPUS; i++)
72 set_cpu_possible(i, true); 72 set_cpu_possible(i, false);
73} 73}
74 74
75void imx_smp_prepare(void) 75void imx_smp_prepare(void)
diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c
index 5faba7a3c95f..204942749e21 100644
--- a/arch/arm/mach-imx/pm-imx6q.c
+++ b/arch/arm/mach-imx/pm-imx6q.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. 2 * Copyright 2011-2013 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd. 3 * Copyright 2011 Linaro Ltd.
4 * 4 *
5 * The code contained herein is licensed under the GNU General Public 5 * The code contained herein is licensed under the GNU General Public
@@ -34,10 +34,12 @@ static int imx6q_pm_enter(suspend_state_t state)
34 case PM_SUSPEND_MEM: 34 case PM_SUSPEND_MEM:
35 imx6q_set_lpm(STOP_POWER_OFF); 35 imx6q_set_lpm(STOP_POWER_OFF);
36 imx_gpc_pre_suspend(); 36 imx_gpc_pre_suspend();
37 imx_anatop_pre_suspend();
37 imx_set_cpu_jump(0, v7_cpu_resume); 38 imx_set_cpu_jump(0, v7_cpu_resume);
38 /* Zzz ... */ 39 /* Zzz ... */
39 cpu_suspend(0, imx6q_suspend_finish); 40 cpu_suspend(0, imx6q_suspend_finish);
40 imx_smp_prepare(); 41 imx_smp_prepare();
42 imx_anatop_post_resume();
41 imx_gpc_post_resume(); 43 imx_gpc_post_resume();
42 imx6q_set_lpm(WAIT_CLOCKED); 44 imx6q_set_lpm(WAIT_CLOCKED);
43 break; 45 break;
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
index 97d086889481..10a6b1a8c5ac 100644
--- a/arch/arm/mach-imx/src.c
+++ b/arch/arm/mach-imx/src.c
@@ -14,6 +14,7 @@
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/of_address.h> 16#include <linux/of_address.h>
17#include <linux/reset-controller.h>
17#include <linux/smp.h> 18#include <linux/smp.h>
18#include <asm/smp_plat.h> 19#include <asm/smp_plat.h>
19#include "common.h" 20#include "common.h"
@@ -21,10 +22,65 @@
21#define SRC_SCR 0x000 22#define SRC_SCR 0x000
22#define SRC_GPR1 0x020 23#define SRC_GPR1 0x020
23#define BP_SRC_SCR_WARM_RESET_ENABLE 0 24#define BP_SRC_SCR_WARM_RESET_ENABLE 0
25#define BP_SRC_SCR_SW_GPU_RST 1
26#define BP_SRC_SCR_SW_VPU_RST 2
27#define BP_SRC_SCR_SW_IPU1_RST 3
28#define BP_SRC_SCR_SW_OPEN_VG_RST 4
29#define BP_SRC_SCR_SW_IPU2_RST 12
24#define BP_SRC_SCR_CORE1_RST 14 30#define BP_SRC_SCR_CORE1_RST 14
25#define BP_SRC_SCR_CORE1_ENABLE 22 31#define BP_SRC_SCR_CORE1_ENABLE 22
26 32
27static void __iomem *src_base; 33static void __iomem *src_base;
34static DEFINE_SPINLOCK(scr_lock);
35
36static const int sw_reset_bits[5] = {
37 BP_SRC_SCR_SW_GPU_RST,
38 BP_SRC_SCR_SW_VPU_RST,
39 BP_SRC_SCR_SW_IPU1_RST,
40 BP_SRC_SCR_SW_OPEN_VG_RST,
41 BP_SRC_SCR_SW_IPU2_RST
42};
43
44static int imx_src_reset_module(struct reset_controller_dev *rcdev,
45 unsigned long sw_reset_idx)
46{
47 unsigned long timeout;
48 unsigned long flags;
49 int bit;
50 u32 val;
51
52 if (!src_base)
53 return -ENODEV;
54
55 if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits))
56 return -EINVAL;
57
58 bit = 1 << sw_reset_bits[sw_reset_idx];
59
60 spin_lock_irqsave(&scr_lock, flags);
61 val = readl_relaxed(src_base + SRC_SCR);
62 val |= bit;
63 writel_relaxed(val, src_base + SRC_SCR);
64 spin_unlock_irqrestore(&scr_lock, flags);
65
66 timeout = jiffies + msecs_to_jiffies(1000);
67 while (readl(src_base + SRC_SCR) & bit) {
68 if (time_after(jiffies, timeout))
69 return -ETIME;
70 cpu_relax();
71 }
72
73 return 0;
74}
75
76static struct reset_control_ops imx_src_ops = {
77 .reset = imx_src_reset_module,
78};
79
80static struct reset_controller_dev imx_reset_controller = {
81 .ops = &imx_src_ops,
82 .nr_resets = ARRAY_SIZE(sw_reset_bits),
83};
28 84
29void imx_enable_cpu(int cpu, bool enable) 85void imx_enable_cpu(int cpu, bool enable)
30{ 86{
@@ -32,9 +88,11 @@ void imx_enable_cpu(int cpu, bool enable)
32 88
33 cpu = cpu_logical_map(cpu); 89 cpu = cpu_logical_map(cpu);
34 mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1); 90 mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
91 spin_lock(&scr_lock);
35 val = readl_relaxed(src_base + SRC_SCR); 92 val = readl_relaxed(src_base + SRC_SCR);
36 val = enable ? val | mask : val & ~mask; 93 val = enable ? val | mask : val & ~mask;
37 writel_relaxed(val, src_base + SRC_SCR); 94 writel_relaxed(val, src_base + SRC_SCR);
95 spin_unlock(&scr_lock);
38} 96}
39 97
40void imx_set_cpu_jump(int cpu, void *jump_addr) 98void imx_set_cpu_jump(int cpu, void *jump_addr)
@@ -61,9 +119,11 @@ void imx_src_prepare_restart(void)
61 u32 val; 119 u32 val;
62 120
63 /* clear enable bits of secondary cores */ 121 /* clear enable bits of secondary cores */
122 spin_lock(&scr_lock);
64 val = readl_relaxed(src_base + SRC_SCR); 123 val = readl_relaxed(src_base + SRC_SCR);
65 val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE); 124 val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE);
66 writel_relaxed(val, src_base + SRC_SCR); 125 writel_relaxed(val, src_base + SRC_SCR);
126 spin_unlock(&scr_lock);
67 127
68 /* clear persistent entry register of primary core */ 128 /* clear persistent entry register of primary core */
69 writel_relaxed(0, src_base + SRC_GPR1); 129 writel_relaxed(0, src_base + SRC_GPR1);
@@ -80,11 +140,17 @@ void __init imx_src_init(void)
80 src_base = of_iomap(np, 0); 140 src_base = of_iomap(np, 0);
81 WARN_ON(!src_base); 141 WARN_ON(!src_base);
82 142
143 imx_reset_controller.of_node = np;
144 if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
145 reset_controller_register(&imx_reset_controller);
146
83 /* 147 /*
84 * force warm reset sources to generate cold reset 148 * force warm reset sources to generate cold reset
85 * for a more reliable restart 149 * for a more reliable restart
86 */ 150 */
151 spin_lock(&scr_lock);
87 val = readl_relaxed(src_base + SRC_SCR); 152 val = readl_relaxed(src_base + SRC_SCR);
88 val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE); 153 val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE);
89 writel_relaxed(val, src_base + SRC_SCR); 154 writel_relaxed(val, src_base + SRC_SCR);
155 spin_unlock(&scr_lock);
90} 156}
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index cdbca328a412..e1f3735d3415 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -1,4 +1,4 @@
1obj-y += common.o addr-map.o irq.o pcie.o mpp.o 1obj-y += common.o irq.o pcie.o mpp.o
2 2
3obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o 3obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o
4obj-$(CONFIG_MACH_DB88F6281_BP) += db88f6281-bp-setup.o 4obj-$(CONFIG_MACH_DB88F6281_BP) += db88f6281-bp-setup.o
diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c
deleted file mode 100644
index 8f0d162a1e1d..000000000000
--- a/arch/arm/mach-kirkwood/addr-map.c
+++ /dev/null
@@ -1,91 +0,0 @@
1/*
2 * arch/arm/mach-kirkwood/addr-map.c
3 *
4 * Address map functions for Marvell Kirkwood SoCs
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/mbus.h>
14#include <linux/io.h>
15#include <mach/hardware.h>
16#include <plat/addr-map.h>
17#include "common.h"
18
19/*
20 * Generic Address Decode Windows bit settings
21 */
22#define TARGET_DEV_BUS 1
23#define TARGET_SRAM 3
24#define TARGET_PCIE 4
25#define ATTR_DEV_SPI_ROM 0x1e
26#define ATTR_DEV_BOOT 0x1d
27#define ATTR_DEV_NAND 0x2f
28#define ATTR_DEV_CS3 0x37
29#define ATTR_DEV_CS2 0x3b
30#define ATTR_DEV_CS1 0x3d
31#define ATTR_DEV_CS0 0x3e
32#define ATTR_PCIE_IO 0xe0
33#define ATTR_PCIE_MEM 0xe8
34#define ATTR_PCIE1_IO 0xd0
35#define ATTR_PCIE1_MEM 0xd8
36#define ATTR_SRAM 0x01
37
38/*
39 * Description of the windows needed by the platform code
40 */
41static struct __initdata orion_addr_map_cfg addr_map_cfg = {
42 .num_wins = 8,
43 .remappable_wins = 4,
44 .bridge_virt_base = BRIDGE_VIRT_BASE,
45};
46
47static const struct __initdata orion_addr_map_info addr_map_info[] = {
48 /*
49 * Windows for PCIe IO+MEM space.
50 */
51 { 0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE,
52 TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE
53 },
54 { 1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
55 TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE
56 },
57 { 2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE,
58 TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE
59 },
60 { 3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE,
61 TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE
62 },
63 /*
64 * Window for NAND controller.
65 */
66 { 4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
67 TARGET_DEV_BUS, ATTR_DEV_NAND, -1
68 },
69 /*
70 * Window for SRAM.
71 */
72 { 5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE,
73 TARGET_SRAM, ATTR_SRAM, -1
74 },
75 /* End marker */
76 { -1, 0, 0, 0, 0, 0 }
77};
78
79void __init kirkwood_setup_cpu_mbus(void)
80{
81 /*
82 * Disable, clear and configure windows.
83 */
84 orion_config_wins(&addr_map_cfg, addr_map_info);
85
86 /*
87 * Setup MBUS dram target info.
88 */
89 orion_setup_cpu_mbus_target(&addr_map_cfg,
90 (void __iomem *) DDR_WINDOW_CPU_BASE);
91}
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index 7904758e771f..e9647b80cb59 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -93,7 +93,7 @@ static void __init kirkwood_dt_init(void)
93 */ 93 */
94 writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG); 94 writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
95 95
96 kirkwood_setup_cpu_mbus(); 96 kirkwood_setup_wins();
97 97
98 kirkwood_l2_init(); 98 kirkwood_l2_init();
99 99
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 49792a0cd2d3..c2cae69e6d2b 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -33,7 +33,6 @@
33#include <linux/platform_data/usb-ehci-orion.h> 33#include <linux/platform_data/usb-ehci-orion.h>
34#include <plat/common.h> 34#include <plat/common.h>
35#include <plat/time.h> 35#include <plat/time.h>
36#include <plat/addr-map.h>
37#include <linux/platform_data/dma-mv_xor.h> 36#include <linux/platform_data/dma-mv_xor.h>
38#include "common.h" 37#include "common.h"
39 38
@@ -535,6 +534,9 @@ void __init kirkwood_init_early(void)
535 * the allocations won't fail. 534 * the allocations won't fail.
536 */ 535 */
537 init_dma_coherent_pool_size(SZ_1M); 536 init_dma_coherent_pool_size(SZ_1M);
537 mvebu_mbus_init("marvell,kirkwood-mbus",
538 BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
539 DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ);
538} 540}
539 541
540int kirkwood_tclk; 542int kirkwood_tclk;
@@ -650,6 +652,38 @@ char * __init kirkwood_id(void)
650 } 652 }
651} 653}
652 654
655void __init kirkwood_setup_wins(void)
656{
657 /*
658 * The PCIe windows will no longer be statically allocated
659 * here once Kirkwood is migrated to the pci-mvebu driver.
660 */
661 mvebu_mbus_add_window_remap_flags("pcie0.0",
662 KIRKWOOD_PCIE_IO_PHYS_BASE,
663 KIRKWOOD_PCIE_IO_SIZE,
664 KIRKWOOD_PCIE_IO_BUS_BASE,
665 MVEBU_MBUS_PCI_IO);
666 mvebu_mbus_add_window_remap_flags("pcie0.0",
667 KIRKWOOD_PCIE_MEM_PHYS_BASE,
668 KIRKWOOD_PCIE_MEM_SIZE,
669 MVEBU_MBUS_NO_REMAP,
670 MVEBU_MBUS_PCI_MEM);
671 mvebu_mbus_add_window_remap_flags("pcie1.0",
672 KIRKWOOD_PCIE1_IO_PHYS_BASE,
673 KIRKWOOD_PCIE1_IO_SIZE,
674 KIRKWOOD_PCIE1_IO_BUS_BASE,
675 MVEBU_MBUS_PCI_IO);
676 mvebu_mbus_add_window_remap_flags("pcie1.0",
677 KIRKWOOD_PCIE1_MEM_PHYS_BASE,
678 KIRKWOOD_PCIE1_MEM_SIZE,
679 MVEBU_MBUS_NO_REMAP,
680 MVEBU_MBUS_PCI_MEM);
681 mvebu_mbus_add_window("nand", KIRKWOOD_NAND_MEM_PHYS_BASE,
682 KIRKWOOD_NAND_MEM_SIZE);
683 mvebu_mbus_add_window("sram", KIRKWOOD_SRAM_PHYS_BASE,
684 KIRKWOOD_SRAM_SIZE);
685}
686
653void __init kirkwood_l2_init(void) 687void __init kirkwood_l2_init(void)
654{ 688{
655#ifdef CONFIG_CACHE_FEROCEON_L2 689#ifdef CONFIG_CACHE_FEROCEON_L2
@@ -675,7 +709,7 @@ void __init kirkwood_init(void)
675 */ 709 */
676 writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG); 710 writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
677 711
678 kirkwood_setup_cpu_mbus(); 712 kirkwood_setup_wins();
679 713
680 kirkwood_l2_init(); 714 kirkwood_l2_init();
681 715
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index 3147be2f34da..21da3b1ebd7b 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -30,7 +30,7 @@ void kirkwood_init(void);
30void kirkwood_init_early(void); 30void kirkwood_init_early(void);
31void kirkwood_init_irq(void); 31void kirkwood_init_irq(void);
32 32
33void kirkwood_setup_cpu_mbus(void); 33void kirkwood_setup_wins(void);
34 34
35void kirkwood_enable_pcie(void); 35void kirkwood_enable_pcie(void);
36void kirkwood_pcie_id(u32 *dev, u32 *rev); 36void kirkwood_pcie_id(u32 *dev, u32 *rev);
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index a05563a31c95..92976cef3910 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -60,8 +60,9 @@
60 * Register Map 60 * Register Map
61 */ 61 */
62#define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x00000) 62#define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x00000)
63#define DDR_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x00000) 63#define DDR_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x00000)
64#define DDR_WINDOW_CPU_BASE (DDR_VIRT_BASE + 0x1500) 64#define DDR_WINDOW_CPU_BASE (DDR_PHYS_BASE + 0x1500)
65#define DDR_WINDOW_CPU_SZ (0x20)
65#define DDR_OPERATION_BASE (DDR_PHYS_BASE + 0x1418) 66#define DDR_OPERATION_BASE (DDR_PHYS_BASE + 0x1418)
66 67
67#define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x10000) 68#define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x10000)
@@ -80,6 +81,8 @@
80 81
81#define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x20000) 82#define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x20000)
82#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x20000) 83#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x20000)
84#define BRIDGE_WINS_BASE (BRIDGE_PHYS_BASE)
85#define BRIDGE_WINS_SZ (0x80)
83 86
84#define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x30000) 87#define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x30000)
85 88
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index d96ad4c09972..7f43e6c2f8c0 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -17,7 +17,6 @@
17#include <asm/mach/pci.h> 17#include <asm/mach/pci.h>
18#include <plat/pcie.h> 18#include <plat/pcie.h>
19#include <mach/bridge-regs.h> 19#include <mach/bridge-regs.h>
20#include <plat/addr-map.h>
21#include "common.h" 20#include "common.h"
22 21
23static void kirkwood_enable_pcie_clk(const char *port) 22static void kirkwood_enable_pcie_clk(const char *port)
diff --git a/arch/arm/mach-mv78xx0/Makefile b/arch/arm/mach-mv78xx0/Makefile
index 67a13f9bfe64..7cd04634d302 100644
--- a/arch/arm/mach-mv78xx0/Makefile
+++ b/arch/arm/mach-mv78xx0/Makefile
@@ -1,4 +1,4 @@
1obj-y += common.o addr-map.o mpp.o irq.o pcie.o 1obj-y += common.o mpp.o irq.o pcie.o
2obj-$(CONFIG_MACH_DB78X00_BP) += db78x00-bp-setup.o 2obj-$(CONFIG_MACH_DB78X00_BP) += db78x00-bp-setup.o
3obj-$(CONFIG_MACH_RD78X00_MASA) += rd78x00-masa-setup.o 3obj-$(CONFIG_MACH_RD78X00_MASA) += rd78x00-masa-setup.o
4obj-$(CONFIG_MACH_TERASTATION_WXL) += buffalo-wxl-setup.o 4obj-$(CONFIG_MACH_TERASTATION_WXL) += buffalo-wxl-setup.o
diff --git a/arch/arm/mach-mv78xx0/addr-map.c b/arch/arm/mach-mv78xx0/addr-map.c
deleted file mode 100644
index 26e9876b50e9..000000000000
--- a/arch/arm/mach-mv78xx0/addr-map.c
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2 * arch/arm/mach-mv78xx0/addr-map.c
3 *
4 * Address map functions for Marvell MV78xx0 SoCs
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/mbus.h>
14#include <linux/io.h>
15#include <plat/addr-map.h>
16#include <mach/mv78xx0.h>
17#include "common.h"
18
19/*
20 * Generic Address Decode Windows bit settings
21 */
22#define TARGET_DEV_BUS 1
23#define TARGET_PCIE0 4
24#define TARGET_PCIE1 8
25#define TARGET_PCIE(i) ((i) ? TARGET_PCIE1 : TARGET_PCIE0)
26#define ATTR_DEV_SPI_ROM 0x1f
27#define ATTR_DEV_BOOT 0x2f
28#define ATTR_DEV_CS3 0x37
29#define ATTR_DEV_CS2 0x3b
30#define ATTR_DEV_CS1 0x3d
31#define ATTR_DEV_CS0 0x3e
32#define ATTR_PCIE_IO(l) (0xf0 & ~(0x10 << (l)))
33#define ATTR_PCIE_MEM(l) (0xf8 & ~(0x10 << (l)))
34
35/*
36 * CPU Address Decode Windows registers
37 */
38#define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4))
39#define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4))
40
41static void __init __iomem *win_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
42{
43 /*
44 * Find the control register base address for this window.
45 *
46 * BRIDGE_VIRT_BASE points to the right (CPU0's or CPU1's)
47 * MBUS bridge depending on which CPU core we're running on,
48 * so we don't need to take that into account here.
49 */
50
51 return (win < 8) ? WIN0_OFF(win) : WIN8_OFF(win);
52}
53
54/*
55 * Description of the windows needed by the platform code
56 */
57static struct orion_addr_map_cfg addr_map_cfg __initdata = {
58 .num_wins = 14,
59 .remappable_wins = 8,
60 .win_cfg_base = win_cfg_base,
61};
62
63void __init mv78xx0_setup_cpu_mbus(void)
64{
65 /*
66 * Disable, clear and configure windows.
67 */
68 orion_config_wins(&addr_map_cfg, NULL);
69
70 /*
71 * Setup MBUS dram target info.
72 */
73 if (mv78xx0_core_index() == 0)
74 orion_setup_cpu_mbus_target(&addr_map_cfg,
75 (void __iomem *) DDR_WINDOW_CPU0_BASE);
76 else
77 orion_setup_cpu_mbus_target(&addr_map_cfg,
78 (void __iomem *) DDR_WINDOW_CPU1_BASE);
79}
80
81void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
82 int maj, int min)
83{
84 orion_setup_cpu_win(&addr_map_cfg, window, base, size,
85 TARGET_PCIE(maj), ATTR_PCIE_IO(min), 0);
86}
87
88void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
89 int maj, int min)
90{
91 orion_setup_cpu_win(&addr_map_cfg, window, base, size,
92 TARGET_PCIE(maj), ATTR_PCIE_MEM(min), -1);
93}
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c
index 0efa14498ebc..749a7f8c4992 100644
--- a/arch/arm/mach-mv78xx0/common.c
+++ b/arch/arm/mach-mv78xx0/common.c
@@ -334,6 +334,14 @@ void __init mv78xx0_uart3_init(void)
334void __init mv78xx0_init_early(void) 334void __init mv78xx0_init_early(void)
335{ 335{
336 orion_time_set_base(TIMER_VIRT_BASE); 336 orion_time_set_base(TIMER_VIRT_BASE);
337 if (mv78xx0_core_index() == 0)
338 mvebu_mbus_init("marvell,mv78xx0-mbus",
339 BRIDGE_WINS_CPU0_BASE, BRIDGE_WINS_SZ,
340 DDR_WINDOW_CPU0_BASE, DDR_WINDOW_CPU_SZ);
341 else
342 mvebu_mbus_init("marvell,mv78xx0-mbus",
343 BRIDGE_WINS_CPU1_BASE, BRIDGE_WINS_SZ,
344 DDR_WINDOW_CPU1_BASE, DDR_WINDOW_CPU_SZ);
337} 345}
338 346
339void __init_refok mv78xx0_timer_init(void) 347void __init_refok mv78xx0_timer_init(void)
@@ -397,8 +405,6 @@ void __init mv78xx0_init(void)
397 printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000); 405 printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
398 printk("TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000); 406 printk("TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000);
399 407
400 mv78xx0_setup_cpu_mbus();
401
402#ifdef CONFIG_CACHE_FEROCEON_L2 408#ifdef CONFIG_CACHE_FEROCEON_L2
403 feroceon_l2_init(is_l2_writethrough()); 409 feroceon_l2_init(is_l2_writethrough());
404#endif 410#endif
diff --git a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
index 46200a183cf2..723748d8ba7d 100644
--- a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
+++ b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
@@ -60,13 +60,18 @@
60 */ 60 */
61#define BRIDGE_VIRT_BASE (MV78XX0_CORE_REGS_VIRT_BASE) 61#define BRIDGE_VIRT_BASE (MV78XX0_CORE_REGS_VIRT_BASE)
62#define BRIDGE_PHYS_BASE (MV78XX0_CORE_REGS_PHYS_BASE) 62#define BRIDGE_PHYS_BASE (MV78XX0_CORE_REGS_PHYS_BASE)
63#define BRIDGE_WINS_CPU0_BASE (MV78XX0_CORE0_REGS_PHYS_BASE)
64#define BRIDGE_WINS_CPU1_BASE (MV78XX0_CORE1_REGS_PHYS_BASE)
65#define BRIDGE_WINS_SZ (0xA000)
63 66
64/* 67/*
65 * Register Map 68 * Register Map
66 */ 69 */
67#define DDR_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x00000) 70#define DDR_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x00000)
68#define DDR_WINDOW_CPU0_BASE (DDR_VIRT_BASE + 0x1500) 71#define DDR_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x00000)
69#define DDR_WINDOW_CPU1_BASE (DDR_VIRT_BASE + 0x1570) 72#define DDR_WINDOW_CPU0_BASE (DDR_PHYS_BASE + 0x1500)
73#define DDR_WINDOW_CPU1_BASE (DDR_PHYS_BASE + 0x1570)
74#define DDR_WINDOW_CPU_SZ (0x20)
70 75
71#define DEV_BUS_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x10000) 76#define DEV_BUS_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x10000)
72#define DEV_BUS_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x10000) 77#define DEV_BUS_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x10000)
diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c
index ee8c0b51df2c..dc26a654c496 100644
--- a/arch/arm/mach-mv78xx0/pcie.c
+++ b/arch/arm/mach-mv78xx0/pcie.c
@@ -10,11 +10,11 @@
10 10
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/pci.h> 12#include <linux/pci.h>
13#include <linux/mbus.h>
13#include <video/vga.h> 14#include <video/vga.h>
14#include <asm/irq.h> 15#include <asm/irq.h>
15#include <asm/mach/pci.h> 16#include <asm/mach/pci.h>
16#include <plat/pcie.h> 17#include <plat/pcie.h>
17#include <plat/addr-map.h>
18#include <mach/mv78xx0.h> 18#include <mach/mv78xx0.h>
19#include "common.h" 19#include "common.h"
20 20
@@ -54,7 +54,6 @@ static void __init mv78xx0_pcie_preinit(void)
54 int i; 54 int i;
55 u32 size_each; 55 u32 size_each;
56 u32 start; 56 u32 start;
57 int win = 0;
58 57
59 pcie_io_space.name = "PCIe I/O Space"; 58 pcie_io_space.name = "PCIe I/O Space";
60 pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0); 59 pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0);
@@ -72,6 +71,7 @@ static void __init mv78xx0_pcie_preinit(void)
72 start = MV78XX0_PCIE_MEM_PHYS_BASE; 71 start = MV78XX0_PCIE_MEM_PHYS_BASE;
73 for (i = 0; i < num_pcie_ports; i++) { 72 for (i = 0; i < num_pcie_ports; i++) {
74 struct pcie_port *pp = pcie_port + i; 73 struct pcie_port *pp = pcie_port + i;
74 char winname[MVEBU_MBUS_MAX_WINNAME_SZ];
75 75
76 snprintf(pp->mem_space_name, sizeof(pp->mem_space_name), 76 snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
77 "PCIe %d.%d MEM", pp->maj, pp->min); 77 "PCIe %d.%d MEM", pp->maj, pp->min);
@@ -85,12 +85,17 @@ static void __init mv78xx0_pcie_preinit(void)
85 if (request_resource(&iomem_resource, &pp->res)) 85 if (request_resource(&iomem_resource, &pp->res))
86 panic("can't allocate PCIe MEM sub-space"); 86 panic("can't allocate PCIe MEM sub-space");
87 87
88 mv78xx0_setup_pcie_mem_win(win + i + 8, pp->res.start, 88 snprintf(winname, sizeof(winname), "pcie%d.%d",
89 resource_size(&pp->res), 89 pp->maj, pp->min);
90 pp->maj, pp->min); 90
91 91 mvebu_mbus_add_window_remap_flags(winname,
92 mv78xx0_setup_pcie_io_win(win + i, i * SZ_64K, SZ_64K, 92 pp->res.start,
93 pp->maj, pp->min); 93 resource_size(&pp->res),
94 MVEBU_MBUS_NO_REMAP,
95 MVEBU_MBUS_PCI_MEM);
96 mvebu_mbus_add_window_remap_flags(winname,
97 i * SZ_64K, SZ_64K,
98 0, MVEBU_MBUS_PCI_IO);
94 } 99 }
95} 100}
96 101
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 440b13ef1fed..e11acbb0a46d 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -13,6 +13,8 @@ config ARCH_MVEBU
13 select MVEBU_CLK_CORE 13 select MVEBU_CLK_CORE
14 select MVEBU_CLK_CPU 14 select MVEBU_CLK_CPU
15 select MVEBU_CLK_GATING 15 select MVEBU_CLK_GATING
16 select MVEBU_MBUS
17 select ZONE_DMA if ARM_LPAE
16 18
17if ARCH_MVEBU 19if ARCH_MVEBU
18 20
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index da93bcbc74c1..ba769e082ad4 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -5,6 +5,6 @@ AFLAGS_coherency_ll.o := -Wa,-march=armv7-a
5 5
6obj-y += system-controller.o 6obj-y += system-controller.o
7obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o 7obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o
8obj-$(CONFIG_ARCH_MVEBU) += addr-map.o coherency.o coherency_ll.o pmsu.o irq-armada-370-xp.o 8obj-$(CONFIG_ARCH_MVEBU) += coherency.o coherency_ll.o pmsu.o irq-armada-370-xp.o
9obj-$(CONFIG_SMP) += platsmp.o headsmp.o 9obj-$(CONFIG_SMP) += platsmp.o headsmp.o
10obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 10obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-mvebu/addr-map.c b/arch/arm/mach-mvebu/addr-map.c
deleted file mode 100644
index ab9b3bd4fef5..000000000000
--- a/arch/arm/mach-mvebu/addr-map.c
+++ /dev/null
@@ -1,137 +0,0 @@
1/*
2 * Address map functions for Marvell 370 / XP SoCs
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#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/mbus.h>
16#include <linux/io.h>
17#include <linux/of.h>
18#include <linux/of_address.h>
19#include <plat/addr-map.h>
20
21/*
22 * Generic Address Decode Windows bit settings
23 */
24#define ARMADA_XP_TARGET_DEV_BUS 1
25#define ARMADA_XP_ATTR_DEV_BOOTROM 0x1D
26#define ARMADA_XP_TARGET_ETH1 3
27#define ARMADA_XP_TARGET_PCIE_0_2 4
28#define ARMADA_XP_TARGET_ETH0 7
29#define ARMADA_XP_TARGET_PCIE_1_3 8
30
31#define ARMADA_370_TARGET_DEV_BUS 1
32#define ARMADA_370_ATTR_DEV_BOOTROM 0x1D
33#define ARMADA_370_TARGET_PCIE_0 4
34#define ARMADA_370_TARGET_PCIE_1 8
35
36#define ARMADA_WINDOW_8_PLUS_OFFSET 0x90
37#define ARMADA_SDRAM_ADDR_DECODING_OFFSET 0x180
38
39static const struct __initdata orion_addr_map_info
40armada_xp_addr_map_info[] = {
41 /*
42 * Window for the BootROM, needed for SMP on Armada XP
43 */
44 { 0, 0xfff00000, SZ_1M, ARMADA_XP_TARGET_DEV_BUS,
45 ARMADA_XP_ATTR_DEV_BOOTROM, -1 },
46 /* End marker */
47 { -1, 0, 0, 0, 0, 0 },
48};
49
50static const struct __initdata orion_addr_map_info
51armada_370_addr_map_info[] = {
52 /* End marker */
53 { -1, 0, 0, 0, 0, 0 },
54};
55
56static struct of_device_id of_addr_decoding_controller_table[] = {
57 { .compatible = "marvell,armada-addr-decoding-controller" },
58 { /* end of list */ },
59};
60
61static void __iomem *
62armada_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
63{
64 unsigned int offset;
65
66 /* The register layout is a bit annoying and the below code
67 * tries to cope with it.
68 * - At offset 0x0, there are the registers for the first 8
69 * windows, with 4 registers of 32 bits per window (ctrl,
70 * base, remap low, remap high)
71 * - Then at offset 0x80, there is a hole of 0x10 bytes for
72 * the internal registers base address and internal units
73 * sync barrier register.
74 * - Then at offset 0x90, there the registers for 12
75 * windows, with only 2 registers of 32 bits per window
76 * (ctrl, base).
77 */
78 if (win < 8)
79 offset = (win << 4);
80 else
81 offset = ARMADA_WINDOW_8_PLUS_OFFSET + ((win - 8) << 3);
82
83 return cfg->bridge_virt_base + offset;
84}
85
86static struct __initdata orion_addr_map_cfg addr_map_cfg = {
87 .num_wins = 20,
88 .remappable_wins = 8,
89 .win_cfg_base = armada_cfg_base,
90};
91
92static int __init armada_setup_cpu_mbus(void)
93{
94 struct device_node *np;
95 void __iomem *mbus_unit_addr_decoding_base;
96 void __iomem *sdram_addr_decoding_base;
97
98 np = of_find_matching_node(NULL, of_addr_decoding_controller_table);
99 if (!np)
100 return -ENODEV;
101
102 mbus_unit_addr_decoding_base = of_iomap(np, 0);
103 BUG_ON(!mbus_unit_addr_decoding_base);
104
105 sdram_addr_decoding_base =
106 mbus_unit_addr_decoding_base +
107 ARMADA_SDRAM_ADDR_DECODING_OFFSET;
108
109 addr_map_cfg.bridge_virt_base = mbus_unit_addr_decoding_base;
110
111 if (of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric"))
112 addr_map_cfg.hw_io_coherency = 1;
113
114 /*
115 * Disable, clear and configure windows.
116 */
117 if (of_machine_is_compatible("marvell,armadaxp"))
118 orion_config_wins(&addr_map_cfg, armada_xp_addr_map_info);
119 else if (of_machine_is_compatible("marvell,armada370"))
120 orion_config_wins(&addr_map_cfg, armada_370_addr_map_info);
121 else {
122 pr_err("Unsupported SoC\n");
123 return -EINVAL;
124 }
125
126 /*
127 * Setup MBUS dram target info.
128 */
129 orion_setup_cpu_mbus_target(&addr_map_cfg,
130 sdram_addr_decoding_base);
131 return 0;
132}
133
134/* Using a early_initcall is needed so that this initialization gets
135 * done before the SMP initialization, which requires the BootROM to
136 * be remapped. */
137early_initcall(armada_setup_cpu_mbus);
diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c
index a5ea616d6d12..12d3655830d1 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.c
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
@@ -19,6 +19,7 @@
19#include <linux/time-armada-370-xp.h> 19#include <linux/time-armada-370-xp.h>
20#include <linux/clk/mvebu.h> 20#include <linux/clk/mvebu.h>
21#include <linux/dma-mapping.h> 21#include <linux/dma-mapping.h>
22#include <linux/mbus.h>
22#include <asm/mach/arch.h> 23#include <asm/mach/arch.h>
23#include <asm/mach/map.h> 24#include <asm/mach/map.h>
24#include <asm/mach/time.h> 25#include <asm/mach/time.h>
@@ -48,12 +49,29 @@ void __init armada_370_xp_timer_and_clk_init(void)
48 49
49void __init armada_370_xp_init_early(void) 50void __init armada_370_xp_init_early(void)
50{ 51{
52 char *mbus_soc_name;
53
51 /* 54 /*
52 * Some Armada 370/XP devices allocate their coherent buffers 55 * Some Armada 370/XP devices allocate their coherent buffers
53 * from atomic context. Increase size of atomic coherent pool 56 * from atomic context. Increase size of atomic coherent pool
54 * to make sure such the allocations won't fail. 57 * to make sure such the allocations won't fail.
55 */ 58 */
56 init_dma_coherent_pool_size(SZ_1M); 59 init_dma_coherent_pool_size(SZ_1M);
60
61 /*
62 * This initialization will be replaced by a DT-based
63 * initialization once the mvebu-mbus driver gains DT support.
64 */
65 if (of_machine_is_compatible("marvell,armada370"))
66 mbus_soc_name = "marvell,armada370-mbus";
67 else
68 mbus_soc_name = "marvell,armadaxp-mbus";
69
70 mvebu_mbus_init(mbus_soc_name,
71 ARMADA_370_XP_MBUS_WINS_BASE,
72 ARMADA_370_XP_MBUS_WINS_SIZE,
73 ARMADA_370_XP_SDRAM_WINS_BASE,
74 ARMADA_370_XP_SDRAM_WINS_SIZE);
57} 75}
58 76
59static void __init armada_370_xp_dt_init(void) 77static void __init armada_370_xp_dt_init(void)
diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h
index c6a7d74fddfe..2070e1b4f342 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.h
+++ b/arch/arm/mach-mvebu/armada-370-xp.h
@@ -16,9 +16,15 @@
16#define __MACH_ARMADA_370_XP_H 16#define __MACH_ARMADA_370_XP_H
17 17
18#define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000 18#define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000
19#define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfeb00000) 19#define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfec00000)
20#define ARMADA_370_XP_REGS_SIZE SZ_1M 20#define ARMADA_370_XP_REGS_SIZE SZ_1M
21 21
22/* These defines can go away once mvebu-mbus has a DT binding */
23#define ARMADA_370_XP_MBUS_WINS_BASE (ARMADA_370_XP_REGS_PHYS_BASE + 0x20000)
24#define ARMADA_370_XP_MBUS_WINS_SIZE 0x100
25#define ARMADA_370_XP_SDRAM_WINS_BASE (ARMADA_370_XP_REGS_PHYS_BASE + 0x20180)
26#define ARMADA_370_XP_SDRAM_WINS_SIZE 0x20
27
22#ifdef CONFIG_SMP 28#ifdef CONFIG_SMP
23#include <linux/cpumask.h> 29#include <linux/cpumask.h>
24 30
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
index fe16aaf7c19c..875ea748391c 100644
--- a/arch/arm/mach-mvebu/platsmp.c
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -21,6 +21,7 @@
21#include <linux/smp.h> 21#include <linux/smp.h>
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/of.h> 23#include <linux/of.h>
24#include <linux/mbus.h>
24#include <asm/cacheflush.h> 25#include <asm/cacheflush.h>
25#include <asm/smp_plat.h> 26#include <asm/smp_plat.h>
26#include "common.h" 27#include "common.h"
@@ -109,6 +110,7 @@ void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
109 set_secondary_cpus_clock(); 110 set_secondary_cpus_clock();
110 flush_cache_all(); 111 flush_cache_all();
111 set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0); 112 set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
113 mvebu_mbus_add_window("bootrom", 0xfff00000, SZ_1M);
112} 114}
113 115
114struct smp_operations armada_xp_smp_ops __initdata = { 116struct smp_operations armada_xp_smp_ops __initdata = {
diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile
index 9e809a7c05c0..45da805fb236 100644
--- a/arch/arm/mach-orion5x/Makefile
+++ b/arch/arm/mach-orion5x/Makefile
@@ -1,4 +1,4 @@
1obj-y += common.o addr-map.o pci.o irq.o mpp.o 1obj-y += common.o pci.o irq.o mpp.o
2obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o 2obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o
3obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o 3obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o
4obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o 4obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o
diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c
deleted file mode 100644
index b5efc0fd31cb..000000000000
--- a/arch/arm/mach-orion5x/addr-map.c
+++ /dev/null
@@ -1,155 +0,0 @@
1/*
2 * arch/arm/mach-orion5x/addr-map.c
3 *
4 * Address map functions for Marvell Orion 5x SoCs
5 *
6 * Maintainer: Tzachi Perelstein <tzachi@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 <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/mbus.h>
16#include <linux/io.h>
17#include <mach/hardware.h>
18#include <plat/addr-map.h>
19#include "common.h"
20
21/*
22 * The Orion has fully programmable address map. There's a separate address
23 * map for each of the device _master_ interfaces, e.g. CPU, PCI, PCIe, USB,
24 * Gigabit Ethernet, DMA/XOR engines, etc. Each interface has its own
25 * address decode windows that allow it to access any of the Orion resources.
26 *
27 * CPU address decoding --
28 * Linux assumes that it is the boot loader that already setup the access to
29 * DDR and internal registers.
30 * Setup access to PCI and PCIe IO/MEM space is issued by this file.
31 * Setup access to various devices located on the device bus interface (e.g.
32 * flashes, RTC, etc) should be issued by machine-setup.c according to
33 * specific board population (by using orion5x_setup_*_win()).
34 *
35 * Non-CPU Masters address decoding --
36 * Unlike the CPU, we setup the access from Orion's master interfaces to DDR
37 * banks only (the typical use case).
38 * Setup access for each master to DDR is issued by platform device setup.
39 */
40
41/*
42 * Generic Address Decode Windows bit settings
43 */
44#define TARGET_DEV_BUS 1
45#define TARGET_PCI 3
46#define TARGET_PCIE 4
47#define TARGET_SRAM 9
48#define ATTR_PCIE_MEM 0x59
49#define ATTR_PCIE_IO 0x51
50#define ATTR_PCIE_WA 0x79
51#define ATTR_PCI_MEM 0x59
52#define ATTR_PCI_IO 0x51
53#define ATTR_DEV_CS0 0x1e
54#define ATTR_DEV_CS1 0x1d
55#define ATTR_DEV_CS2 0x1b
56#define ATTR_DEV_BOOT 0xf
57#define ATTR_SRAM 0x0
58
59static int __initdata win_alloc_count;
60
61static int __init cpu_win_can_remap(const struct orion_addr_map_cfg *cfg,
62 const int win)
63{
64 u32 dev, rev;
65
66 orion5x_pcie_id(&dev, &rev);
67 if ((dev == MV88F5281_DEV_ID && win < 4)
68 || (dev == MV88F5182_DEV_ID && win < 2)
69 || (dev == MV88F5181_DEV_ID && win < 2)
70 || (dev == MV88F6183_DEV_ID && win < 4))
71 return 1;
72
73 return 0;
74}
75
76/*
77 * Description of the windows needed by the platform code
78 */
79static struct orion_addr_map_cfg addr_map_cfg __initdata = {
80 .num_wins = 8,
81 .cpu_win_can_remap = cpu_win_can_remap,
82 .bridge_virt_base = ORION5X_BRIDGE_VIRT_BASE,
83};
84
85static const struct __initdata orion_addr_map_info addr_map_info[] = {
86 /*
87 * Setup windows for PCI+PCIe IO+MEM space.
88 */
89 { 0, ORION5X_PCIE_IO_PHYS_BASE, ORION5X_PCIE_IO_SIZE,
90 TARGET_PCIE, ATTR_PCIE_IO, ORION5X_PCIE_IO_BUS_BASE
91 },
92 { 1, ORION5X_PCI_IO_PHYS_BASE, ORION5X_PCI_IO_SIZE,
93 TARGET_PCI, ATTR_PCI_IO, ORION5X_PCI_IO_BUS_BASE
94 },
95 { 2, ORION5X_PCIE_MEM_PHYS_BASE, ORION5X_PCIE_MEM_SIZE,
96 TARGET_PCIE, ATTR_PCIE_MEM, -1
97 },
98 { 3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE,
99 TARGET_PCI, ATTR_PCI_MEM, -1
100 },
101 /* End marker */
102 { -1, 0, 0, 0, 0, 0 }
103};
104
105void __init orion5x_setup_cpu_mbus_bridge(void)
106{
107 /*
108 * Disable, clear and configure windows.
109 */
110 orion_config_wins(&addr_map_cfg, addr_map_info);
111 win_alloc_count = 4;
112
113 /*
114 * Setup MBUS dram target info.
115 */
116 orion_setup_cpu_mbus_target(&addr_map_cfg,
117 (void __iomem *) ORION5X_DDR_WINDOW_CPU_BASE);
118}
119
120void __init orion5x_setup_dev_boot_win(u32 base, u32 size)
121{
122 orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
123 TARGET_DEV_BUS, ATTR_DEV_BOOT, -1);
124}
125
126void __init orion5x_setup_dev0_win(u32 base, u32 size)
127{
128 orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
129 TARGET_DEV_BUS, ATTR_DEV_CS0, -1);
130}
131
132void __init orion5x_setup_dev1_win(u32 base, u32 size)
133{
134 orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
135 TARGET_DEV_BUS, ATTR_DEV_CS1, -1);
136}
137
138void __init orion5x_setup_dev2_win(u32 base, u32 size)
139{
140 orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
141 TARGET_DEV_BUS, ATTR_DEV_CS2, -1);
142}
143
144void __init orion5x_setup_pcie_wa_win(u32 base, u32 size)
145{
146 orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
147 TARGET_PCIE, ATTR_PCIE_WA, -1);
148}
149
150void __init orion5x_setup_sram_win(void)
151{
152 orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++,
153 ORION5X_SRAM_PHYS_BASE, ORION5X_SRAM_SIZE,
154 TARGET_SRAM, ATTR_SRAM, -1);
155}
diff --git a/arch/arm/mach-orion5x/board-dt.c b/arch/arm/mach-orion5x/board-dt.c
index 94fbb815680c..b91002ca92f3 100644
--- a/arch/arm/mach-orion5x/board-dt.c
+++ b/arch/arm/mach-orion5x/board-dt.c
@@ -42,7 +42,7 @@ static void __init orion5x_dt_init(void)
42 /* 42 /*
43 * Setup Orion address map 43 * Setup Orion address map
44 */ 44 */
45 orion5x_setup_cpu_mbus_bridge(); 45 orion5x_setup_wins();
46 46
47 /* Setup root of clk tree */ 47 /* Setup root of clk tree */
48 clk_init(); 48 clk_init();
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index 2075bf8e3d90..b97fd672e89d 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -35,7 +35,6 @@
35#include <linux/platform_data/usb-ehci-orion.h> 35#include <linux/platform_data/usb-ehci-orion.h>
36#include <plat/time.h> 36#include <plat/time.h>
37#include <plat/common.h> 37#include <plat/common.h>
38#include <plat/addr-map.h>
39#include "common.h" 38#include "common.h"
40 39
41/***************************************************************************** 40/*****************************************************************************
@@ -175,7 +174,8 @@ void __init orion5x_xor_init(void)
175 ****************************************************************************/ 174 ****************************************************************************/
176static void __init orion5x_crypto_init(void) 175static void __init orion5x_crypto_init(void)
177{ 176{
178 orion5x_setup_sram_win(); 177 mvebu_mbus_add_window("sram", ORION5X_SRAM_PHYS_BASE,
178 ORION5X_SRAM_SIZE);
179 orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE, 179 orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE,
180 SZ_8K, IRQ_ORION5X_CESA); 180 SZ_8K, IRQ_ORION5X_CESA);
181} 181}
@@ -194,6 +194,9 @@ void __init orion5x_wdt_init(void)
194 ****************************************************************************/ 194 ****************************************************************************/
195void __init orion5x_init_early(void) 195void __init orion5x_init_early(void)
196{ 196{
197 u32 rev, dev;
198 const char *mbus_soc_name;
199
197 orion_time_set_base(TIMER_VIRT_BASE); 200 orion_time_set_base(TIMER_VIRT_BASE);
198 201
199 /* 202 /*
@@ -202,6 +205,46 @@ void __init orion5x_init_early(void)
202 * the allocations won't fail. 205 * the allocations won't fail.
203 */ 206 */
204 init_dma_coherent_pool_size(SZ_1M); 207 init_dma_coherent_pool_size(SZ_1M);
208
209 /* Initialize the MBUS driver */
210 orion5x_pcie_id(&dev, &rev);
211 if (dev == MV88F5281_DEV_ID)
212 mbus_soc_name = "marvell,orion5x-88f5281-mbus";
213 else if (dev == MV88F5182_DEV_ID)
214 mbus_soc_name = "marvell,orion5x-88f5182-mbus";
215 else if (dev == MV88F5181_DEV_ID)
216 mbus_soc_name = "marvell,orion5x-88f5181-mbus";
217 else if (dev == MV88F6183_DEV_ID)
218 mbus_soc_name = "marvell,orion5x-88f6183-mbus";
219 else
220 mbus_soc_name = NULL;
221 mvebu_mbus_init(mbus_soc_name, ORION5X_BRIDGE_WINS_BASE,
222 ORION5X_BRIDGE_WINS_SZ,
223 ORION5X_DDR_WINS_BASE, ORION5X_DDR_WINS_SZ);
224}
225
226void orion5x_setup_wins(void)
227{
228 /*
229 * The PCIe windows will no longer be statically allocated
230 * here once Orion5x is migrated to the pci-mvebu driver.
231 */
232 mvebu_mbus_add_window_remap_flags("pcie0.0", ORION5X_PCIE_IO_PHYS_BASE,
233 ORION5X_PCIE_IO_SIZE,
234 ORION5X_PCIE_IO_BUS_BASE,
235 MVEBU_MBUS_PCI_IO);
236 mvebu_mbus_add_window_remap_flags("pcie0.0", ORION5X_PCIE_MEM_PHYS_BASE,
237 ORION5X_PCIE_MEM_SIZE,
238 MVEBU_MBUS_NO_REMAP,
239 MVEBU_MBUS_PCI_MEM);
240 mvebu_mbus_add_window_remap_flags("pci0.0", ORION5X_PCI_IO_PHYS_BASE,
241 ORION5X_PCI_IO_SIZE,
242 ORION5X_PCI_IO_BUS_BASE,
243 MVEBU_MBUS_PCI_IO);
244 mvebu_mbus_add_window_remap_flags("pci0.0", ORION5X_PCI_MEM_PHYS_BASE,
245 ORION5X_PCI_MEM_SIZE,
246 MVEBU_MBUS_NO_REMAP,
247 MVEBU_MBUS_PCI_MEM);
205} 248}
206 249
207int orion5x_tclk; 250int orion5x_tclk;
@@ -283,7 +326,7 @@ void __init orion5x_init(void)
283 /* 326 /*
284 * Setup Orion address map 327 * Setup Orion address map
285 */ 328 */
286 orion5x_setup_cpu_mbus_bridge(); 329 orion5x_setup_wins();
287 330
288 /* Setup root of clk tree */ 331 /* Setup root of clk tree */
289 clk_init(); 332 clk_init();
diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h
index e60345760283..cdaa01f3d186 100644
--- a/arch/arm/mach-orion5x/common.h
+++ b/arch/arm/mach-orion5x/common.h
@@ -17,18 +17,7 @@ void clk_init(void);
17extern int orion5x_tclk; 17extern int orion5x_tclk;
18extern void orion5x_timer_init(void); 18extern void orion5x_timer_init(void);
19 19
20/* 20void orion5x_setup_wins(void);
21 * Enumerations and functions for Orion windows mapping. Used by Orion core
22 * functions to map its interfaces and by the machine-setup to map its on-
23 * board devices. Details in /mach-orion/addr-map.c
24 */
25void orion5x_setup_cpu_mbus_bridge(void);
26void orion5x_setup_dev_boot_win(u32 base, u32 size);
27void orion5x_setup_dev0_win(u32 base, u32 size);
28void orion5x_setup_dev1_win(u32 base, u32 size);
29void orion5x_setup_dev2_win(u32 base, u32 size);
30void orion5x_setup_pcie_wa_win(u32 base, u32 size);
31void orion5x_setup_sram_win(void);
32 21
33void orion5x_ehci0_init(void); 22void orion5x_ehci0_init(void);
34void orion5x_ehci1_init(void); 23void orion5x_ehci1_init(void);
diff --git a/arch/arm/mach-orion5x/d2net-setup.c b/arch/arm/mach-orion5x/d2net-setup.c
index 57d0af74874d..16c88bbabc98 100644
--- a/arch/arm/mach-orion5x/d2net-setup.c
+++ b/arch/arm/mach-orion5x/d2net-setup.c
@@ -317,8 +317,8 @@ static void __init d2net_init(void)
317 d2net_sata_power_init(); 317 d2net_sata_power_init();
318 orion5x_sata_init(&d2net_sata_data); 318 orion5x_sata_init(&d2net_sata_data);
319 319
320 orion5x_setup_dev_boot_win(D2NET_NOR_BOOT_BASE, 320 mvebu_mbus_add_window("devbus-boot", D2NET_NOR_BOOT_BASE,
321 D2NET_NOR_BOOT_SIZE); 321 D2NET_NOR_BOOT_SIZE);
322 platform_device_register(&d2net_nor_flash); 322 platform_device_register(&d2net_nor_flash);
323 323
324 platform_device_register(&d2net_gpio_buttons); 324 platform_device_register(&d2net_gpio_buttons);
diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c
index 76665640087b..4e1263da38bb 100644
--- a/arch/arm/mach-orion5x/db88f5281-setup.c
+++ b/arch/arm/mach-orion5x/db88f5281-setup.c
@@ -340,16 +340,19 @@ static void __init db88f5281_init(void)
340 orion5x_uart0_init(); 340 orion5x_uart0_init();
341 orion5x_uart1_init(); 341 orion5x_uart1_init();
342 342
343 orion5x_setup_dev_boot_win(DB88F5281_NOR_BOOT_BASE, 343 mvebu_mbus_add_window("devbus-boot", DB88F5281_NOR_BOOT_BASE,
344 DB88F5281_NOR_BOOT_SIZE); 344 DB88F5281_NOR_BOOT_SIZE);
345 platform_device_register(&db88f5281_boot_flash); 345 platform_device_register(&db88f5281_boot_flash);
346 346
347 orion5x_setup_dev0_win(DB88F5281_7SEG_BASE, DB88F5281_7SEG_SIZE); 347 mvebu_mbus_add_window("devbus-cs0", DB88F5281_7SEG_BASE,
348 DB88F5281_7SEG_SIZE);
348 349
349 orion5x_setup_dev1_win(DB88F5281_NOR_BASE, DB88F5281_NOR_SIZE); 350 mvebu_mbus_add_window("devbus-cs1", DB88F5281_NOR_BASE,
351 DB88F5281_NOR_SIZE);
350 platform_device_register(&db88f5281_nor_flash); 352 platform_device_register(&db88f5281_nor_flash);
351 353
352 orion5x_setup_dev2_win(DB88F5281_NAND_BASE, DB88F5281_NAND_SIZE); 354 mvebu_mbus_add_window("devbus-cs2", DB88F5281_NAND_BASE,
355 DB88F5281_NAND_SIZE);
353 platform_device_register(&db88f5281_nand_flash); 356 platform_device_register(&db88f5281_nand_flash);
354 357
355 i2c_register_board_info(0, &db88f5281_i2c_rtc, 1); 358 i2c_register_board_info(0, &db88f5281_i2c_rtc, 1);
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c
index 6eb1732757fd..9e6baf581ed3 100644
--- a/arch/arm/mach-orion5x/dns323-setup.c
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -611,7 +611,8 @@ static void __init dns323_init(void)
611 /* setup flash mapping 611 /* setup flash mapping
612 * CS3 holds a 8 MB Spansion S29GL064M90TFIR4 612 * CS3 holds a 8 MB Spansion S29GL064M90TFIR4
613 */ 613 */
614 orion5x_setup_dev_boot_win(DNS323_NOR_BOOT_BASE, DNS323_NOR_BOOT_SIZE); 614 mvebu_mbus_add_window("devbus-boot", DNS323_NOR_BOOT_BASE,
615 DNS323_NOR_BOOT_SIZE);
615 platform_device_register(&dns323_nor_flash); 616 platform_device_register(&dns323_nor_flash);
616 617
617 /* Sort out LEDs, Buttons and i2c devices */ 618 /* Sort out LEDs, Buttons and i2c devices */
diff --git a/arch/arm/mach-orion5x/edmini_v2-setup.c b/arch/arm/mach-orion5x/edmini_v2-setup.c
index d675e727803d..147615510dd0 100644
--- a/arch/arm/mach-orion5x/edmini_v2-setup.c
+++ b/arch/arm/mach-orion5x/edmini_v2-setup.c
@@ -154,8 +154,8 @@ void __init edmini_v2_init(void)
154 orion5x_ehci0_init(); 154 orion5x_ehci0_init();
155 orion5x_eth_init(&edmini_v2_eth_data); 155 orion5x_eth_init(&edmini_v2_eth_data);
156 156
157 orion5x_setup_dev_boot_win(EDMINI_V2_NOR_BOOT_BASE, 157 mvebu_mbus_add_window("devbus-boot", EDMINI_V2_NOR_BOOT_BASE,
158 EDMINI_V2_NOR_BOOT_SIZE); 158 EDMINI_V2_NOR_BOOT_SIZE);
159 platform_device_register(&edmini_v2_nor_flash); 159 platform_device_register(&edmini_v2_nor_flash);
160 160
161 pr_notice("edmini_v2: USB device port, flash write and power-off " 161 pr_notice("edmini_v2: USB device port, flash write and power-off "
diff --git a/arch/arm/mach-orion5x/include/mach/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h
index d265f5484a8e..b78ff3248868 100644
--- a/arch/arm/mach-orion5x/include/mach/orion5x.h
+++ b/arch/arm/mach-orion5x/include/mach/orion5x.h
@@ -66,8 +66,10 @@
66 * Orion Registers Map 66 * Orion Registers Map
67 ******************************************************************************/ 67 ******************************************************************************/
68 68
69#define ORION5X_DDR_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x00000)
70#define ORION5X_DDR_WINS_BASE (ORION5X_DDR_PHYS_BASE + 0x1500)
71#define ORION5X_DDR_WINS_SZ (0x10)
69#define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x00000) 72#define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x00000)
70#define ORION5X_DDR_WINDOW_CPU_BASE (ORION5X_DDR_VIRT_BASE + 0x1500)
71#define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x10000) 73#define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x10000)
72#define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x10000) 74#define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x10000)
73#define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE + (x)) 75#define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE + (x))
@@ -81,6 +83,8 @@
81 83
82#define ORION5X_BRIDGE_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x20000) 84#define ORION5X_BRIDGE_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x20000)
83#define ORION5X_BRIDGE_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x20000) 85#define ORION5X_BRIDGE_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x20000)
86#define ORION5X_BRIDGE_WINS_BASE (ORION5X_BRIDGE_PHYS_BASE)
87#define ORION5X_BRIDGE_WINS_SZ (0x80)
84 88
85#define ORION5X_PCI_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x30000) 89#define ORION5X_PCI_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x30000)
86 90
diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c
index b98403526218..aae10e4a917c 100644
--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c
+++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c
@@ -359,13 +359,13 @@ static void __init kurobox_pro_init(void)
359 orion5x_uart1_init(); 359 orion5x_uart1_init();
360 orion5x_xor_init(); 360 orion5x_xor_init();
361 361
362 orion5x_setup_dev_boot_win(KUROBOX_PRO_NOR_BOOT_BASE, 362 mvebu_mbus_add_window("devbus-boot", KUROBOX_PRO_NOR_BOOT_BASE,
363 KUROBOX_PRO_NOR_BOOT_SIZE); 363 KUROBOX_PRO_NOR_BOOT_SIZE);
364 platform_device_register(&kurobox_pro_nor_flash); 364 platform_device_register(&kurobox_pro_nor_flash);
365 365
366 if (machine_is_kurobox_pro()) { 366 if (machine_is_kurobox_pro()) {
367 orion5x_setup_dev0_win(KUROBOX_PRO_NAND_BASE, 367 mvebu_mbus_add_window("devbus-cs0", KUROBOX_PRO_NAND_BASE,
368 KUROBOX_PRO_NAND_SIZE); 368 KUROBOX_PRO_NAND_SIZE);
369 platform_device_register(&kurobox_pro_nand_flash); 369 platform_device_register(&kurobox_pro_nand_flash);
370 } 370 }
371 371
diff --git a/arch/arm/mach-orion5x/ls-chl-setup.c b/arch/arm/mach-orion5x/ls-chl-setup.c
index 044da5b6a6ae..24f4e14e5893 100644
--- a/arch/arm/mach-orion5x/ls-chl-setup.c
+++ b/arch/arm/mach-orion5x/ls-chl-setup.c
@@ -294,8 +294,8 @@ static void __init lschl_init(void)
294 orion5x_uart0_init(); 294 orion5x_uart0_init();
295 orion5x_xor_init(); 295 orion5x_xor_init();
296 296
297 orion5x_setup_dev_boot_win(LSCHL_NOR_BOOT_BASE, 297 mvebu_mbus_add_window("devbus-boot", LSCHL_NOR_BOOT_BASE,
298 LSCHL_NOR_BOOT_SIZE); 298 LSCHL_NOR_BOOT_SIZE);
299 platform_device_register(&lschl_nor_flash); 299 platform_device_register(&lschl_nor_flash);
300 300
301 platform_device_register(&lschl_leds); 301 platform_device_register(&lschl_leds);
diff --git a/arch/arm/mach-orion5x/ls_hgl-setup.c b/arch/arm/mach-orion5x/ls_hgl-setup.c
index d49f93423f52..fc653bb41e78 100644
--- a/arch/arm/mach-orion5x/ls_hgl-setup.c
+++ b/arch/arm/mach-orion5x/ls_hgl-setup.c
@@ -243,8 +243,8 @@ static void __init ls_hgl_init(void)
243 orion5x_uart0_init(); 243 orion5x_uart0_init();
244 orion5x_xor_init(); 244 orion5x_xor_init();
245 245
246 orion5x_setup_dev_boot_win(LS_HGL_NOR_BOOT_BASE, 246 mvebu_mbus_add_window("devbus-boot", LS_HGL_NOR_BOOT_BASE,
247 LS_HGL_NOR_BOOT_SIZE); 247 LS_HGL_NOR_BOOT_SIZE);
248 platform_device_register(&ls_hgl_nor_flash); 248 platform_device_register(&ls_hgl_nor_flash);
249 249
250 platform_device_register(&ls_hgl_button_device); 250 platform_device_register(&ls_hgl_button_device);
diff --git a/arch/arm/mach-orion5x/lsmini-setup.c b/arch/arm/mach-orion5x/lsmini-setup.c
index 8e3965c6c0fe..18e66e617dc2 100644
--- a/arch/arm/mach-orion5x/lsmini-setup.c
+++ b/arch/arm/mach-orion5x/lsmini-setup.c
@@ -244,8 +244,8 @@ static void __init lsmini_init(void)
244 orion5x_uart0_init(); 244 orion5x_uart0_init();
245 orion5x_xor_init(); 245 orion5x_xor_init();
246 246
247 orion5x_setup_dev_boot_win(LSMINI_NOR_BOOT_BASE, 247 mvebu_mbus_add_window("devbus-boot", LSMINI_NOR_BOOT_BASE,
248 LSMINI_NOR_BOOT_SIZE); 248 LSMINI_NOR_BOOT_SIZE);
249 platform_device_register(&lsmini_nor_flash); 249 platform_device_register(&lsmini_nor_flash);
250 250
251 platform_device_register(&lsmini_button_device); 251 platform_device_register(&lsmini_button_device);
diff --git a/arch/arm/mach-orion5x/mss2-setup.c b/arch/arm/mach-orion5x/mss2-setup.c
index 0ec94a1f2b16..827acbafc9dc 100644
--- a/arch/arm/mach-orion5x/mss2-setup.c
+++ b/arch/arm/mach-orion5x/mss2-setup.c
@@ -241,7 +241,8 @@ static void __init mss2_init(void)
241 orion5x_uart0_init(); 241 orion5x_uart0_init();
242 orion5x_xor_init(); 242 orion5x_xor_init();
243 243
244 orion5x_setup_dev_boot_win(MSS2_NOR_BOOT_BASE, MSS2_NOR_BOOT_SIZE); 244 mvebu_mbus_add_window("devbus-boot", MSS2_NOR_BOOT_BASE,
245 MSS2_NOR_BOOT_SIZE);
245 platform_device_register(&mss2_nor_flash); 246 platform_device_register(&mss2_nor_flash);
246 247
247 platform_device_register(&mss2_button_device); 248 platform_device_register(&mss2_button_device);
diff --git a/arch/arm/mach-orion5x/mv2120-setup.c b/arch/arm/mach-orion5x/mv2120-setup.c
index 18143f2a9093..92600ae2b4b6 100644
--- a/arch/arm/mach-orion5x/mv2120-setup.c
+++ b/arch/arm/mach-orion5x/mv2120-setup.c
@@ -204,7 +204,8 @@ static void __init mv2120_init(void)
204 orion5x_uart0_init(); 204 orion5x_uart0_init();
205 orion5x_xor_init(); 205 orion5x_xor_init();
206 206
207 orion5x_setup_dev_boot_win(MV2120_NOR_BOOT_BASE, MV2120_NOR_BOOT_SIZE); 207 mvebu_mbus_add_window("devbus-boot", MV2120_NOR_BOOT_BASE,
208 MV2120_NOR_BOOT_SIZE);
208 platform_device_register(&mv2120_nor_flash); 209 platform_device_register(&mv2120_nor_flash);
209 210
210 platform_device_register(&mv2120_button_device); 211 platform_device_register(&mv2120_button_device);
diff --git a/arch/arm/mach-orion5x/net2big-setup.c b/arch/arm/mach-orion5x/net2big-setup.c
index 282e503b003e..dd0641a0d074 100644
--- a/arch/arm/mach-orion5x/net2big-setup.c
+++ b/arch/arm/mach-orion5x/net2big-setup.c
@@ -397,8 +397,8 @@ static void __init net2big_init(void)
397 net2big_sata_power_init(); 397 net2big_sata_power_init();
398 orion5x_sata_init(&net2big_sata_data); 398 orion5x_sata_init(&net2big_sata_data);
399 399
400 orion5x_setup_dev_boot_win(NET2BIG_NOR_BOOT_BASE, 400 mvebu_mbus_add_window("devbus-boot", NET2BIG_NOR_BOOT_BASE,
401 NET2BIG_NOR_BOOT_SIZE); 401 NET2BIG_NOR_BOOT_SIZE);
402 platform_device_register(&net2big_nor_flash); 402 platform_device_register(&net2big_nor_flash);
403 403
404 platform_device_register(&net2big_gpio_buttons); 404 platform_device_register(&net2big_gpio_buttons);
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c
index 973db98a3c27..503368023bb1 100644
--- a/arch/arm/mach-orion5x/pci.c
+++ b/arch/arm/mach-orion5x/pci.c
@@ -157,8 +157,11 @@ static int __init pcie_setup(struct pci_sys_data *sys)
157 if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) { 157 if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) {
158 printk(KERN_NOTICE "Applying Orion-1/Orion-NAS PCIe config " 158 printk(KERN_NOTICE "Applying Orion-1/Orion-NAS PCIe config "
159 "read transaction workaround\n"); 159 "read transaction workaround\n");
160 orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE, 160 mvebu_mbus_add_window_remap_flags("pcie0.0",
161 ORION5X_PCIE_WA_SIZE); 161 ORION5X_PCIE_WA_PHYS_BASE,
162 ORION5X_PCIE_WA_SIZE,
163 MVEBU_MBUS_NO_REMAP,
164 MVEBU_MBUS_PCI_WA);
162 pcie_ops.read = pcie_rd_conf_wa; 165 pcie_ops.read = pcie_rd_conf_wa;
163 } 166 }
164 167
diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
index d6e72f672afb..1c4498bf650a 100644
--- a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
@@ -123,8 +123,8 @@ static void __init rd88f5181l_fxo_init(void)
123 orion5x_eth_switch_init(&rd88f5181l_fxo_switch_plat_data, NO_IRQ); 123 orion5x_eth_switch_init(&rd88f5181l_fxo_switch_plat_data, NO_IRQ);
124 orion5x_uart0_init(); 124 orion5x_uart0_init();
125 125
126 orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE, 126 mvebu_mbus_add_window("devbus-boot", RD88F5181L_FXO_NOR_BOOT_BASE,
127 RD88F5181L_FXO_NOR_BOOT_SIZE); 127 RD88F5181L_FXO_NOR_BOOT_SIZE);
128 platform_device_register(&rd88f5181l_fxo_nor_boot_flash); 128 platform_device_register(&rd88f5181l_fxo_nor_boot_flash);
129} 129}
130 130
diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
index c8b7913310e5..adabe34c4fc6 100644
--- a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
@@ -130,8 +130,8 @@ static void __init rd88f5181l_ge_init(void)
130 orion5x_i2c_init(); 130 orion5x_i2c_init();
131 orion5x_uart0_init(); 131 orion5x_uart0_init();
132 132
133 orion5x_setup_dev_boot_win(RD88F5181L_GE_NOR_BOOT_BASE, 133 mvebu_mbus_add_window("devbus-boot", RD88F5181L_GE_NOR_BOOT_BASE,
134 RD88F5181L_GE_NOR_BOOT_SIZE); 134 RD88F5181L_GE_NOR_BOOT_SIZE);
135 platform_device_register(&rd88f5181l_ge_nor_boot_flash); 135 platform_device_register(&rd88f5181l_ge_nor_boot_flash);
136 136
137 i2c_register_board_info(0, &rd88f5181l_ge_i2c_rtc, 1); 137 i2c_register_board_info(0, &rd88f5181l_ge_i2c_rtc, 1);
diff --git a/arch/arm/mach-orion5x/rd88f5182-setup.c b/arch/arm/mach-orion5x/rd88f5182-setup.c
index f9e156725d7c..66e77ec91532 100644
--- a/arch/arm/mach-orion5x/rd88f5182-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5182-setup.c
@@ -264,10 +264,11 @@ static void __init rd88f5182_init(void)
264 orion5x_uart0_init(); 264 orion5x_uart0_init();
265 orion5x_xor_init(); 265 orion5x_xor_init();
266 266
267 orion5x_setup_dev_boot_win(RD88F5182_NOR_BOOT_BASE, 267 mvebu_mbus_add_window("devbus-boot", RD88F5182_NOR_BOOT_BASE,
268 RD88F5182_NOR_BOOT_SIZE); 268 RD88F5182_NOR_BOOT_SIZE);
269 269
270 orion5x_setup_dev1_win(RD88F5182_NOR_BASE, RD88F5182_NOR_SIZE); 270 mvebu_mbus_add_window("devbus-cs1", RD88F5182_NOR_BASE,
271 RD88F5182_NOR_SIZE);
271 platform_device_register(&rd88f5182_nor_flash); 272 platform_device_register(&rd88f5182_nor_flash);
272 platform_device_register(&rd88f5182_gpio_leds); 273 platform_device_register(&rd88f5182_gpio_leds);
273 274
diff --git a/arch/arm/mach-orion5x/terastation_pro2-setup.c b/arch/arm/mach-orion5x/terastation_pro2-setup.c
index acc0877ec1c9..a0bfa53e7556 100644
--- a/arch/arm/mach-orion5x/terastation_pro2-setup.c
+++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c
@@ -329,8 +329,8 @@ static void __init tsp2_init(void)
329 /* 329 /*
330 * Configure peripherals. 330 * Configure peripherals.
331 */ 331 */
332 orion5x_setup_dev_boot_win(TSP2_NOR_BOOT_BASE, 332 mvebu_mbus_add_window("devbus-boot", TSP2_NOR_BOOT_BASE,
333 TSP2_NOR_BOOT_SIZE); 333 TSP2_NOR_BOOT_SIZE);
334 platform_device_register(&tsp2_nor_flash); 334 platform_device_register(&tsp2_nor_flash);
335 335
336 orion5x_ehci0_init(); 336 orion5x_ehci0_init();
diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c
index 9c17f0c2b488..80174f0f168e 100644
--- a/arch/arm/mach-orion5x/ts209-setup.c
+++ b/arch/arm/mach-orion5x/ts209-setup.c
@@ -286,8 +286,8 @@ static void __init qnap_ts209_init(void)
286 /* 286 /*
287 * Configure peripherals. 287 * Configure peripherals.
288 */ 288 */
289 orion5x_setup_dev_boot_win(QNAP_TS209_NOR_BOOT_BASE, 289 mvebu_mbus_add_window("devbus-boot", QNAP_TS209_NOR_BOOT_BASE,
290 QNAP_TS209_NOR_BOOT_SIZE); 290 QNAP_TS209_NOR_BOOT_SIZE);
291 platform_device_register(&qnap_ts209_nor_flash); 291 platform_device_register(&qnap_ts209_nor_flash);
292 292
293 orion5x_ehci0_init(); 293 orion5x_ehci0_init();
diff --git a/arch/arm/mach-orion5x/ts409-setup.c b/arch/arm/mach-orion5x/ts409-setup.c
index 8cc5ab6c503e..92592790d6da 100644
--- a/arch/arm/mach-orion5x/ts409-setup.c
+++ b/arch/arm/mach-orion5x/ts409-setup.c
@@ -277,8 +277,8 @@ static void __init qnap_ts409_init(void)
277 /* 277 /*
278 * Configure peripherals. 278 * Configure peripherals.
279 */ 279 */
280 orion5x_setup_dev_boot_win(QNAP_TS409_NOR_BOOT_BASE, 280 mvebu_mbus_add_window("devbus-boot", QNAP_TS409_NOR_BOOT_BASE,
281 QNAP_TS409_NOR_BOOT_SIZE); 281 QNAP_TS409_NOR_BOOT_SIZE);
282 platform_device_register(&qnap_ts409_nor_flash); 282 platform_device_register(&qnap_ts409_nor_flash);
283 283
284 orion5x_ehci0_init(); 284 orion5x_ehci0_init();
diff --git a/arch/arm/mach-orion5x/wnr854t-setup.c b/arch/arm/mach-orion5x/wnr854t-setup.c
index 66552ca7e05d..6b84863c018d 100644
--- a/arch/arm/mach-orion5x/wnr854t-setup.c
+++ b/arch/arm/mach-orion5x/wnr854t-setup.c
@@ -127,8 +127,8 @@ static void __init wnr854t_init(void)
127 orion5x_eth_switch_init(&wnr854t_switch_plat_data, NO_IRQ); 127 orion5x_eth_switch_init(&wnr854t_switch_plat_data, NO_IRQ);
128 orion5x_uart0_init(); 128 orion5x_uart0_init();
129 129
130 orion5x_setup_dev_boot_win(WNR854T_NOR_BOOT_BASE, 130 mvebu_mbus_add_window("devbus-boot", WNR854T_NOR_BOOT_BASE,
131 WNR854T_NOR_BOOT_SIZE); 131 WNR854T_NOR_BOOT_SIZE);
132 platform_device_register(&wnr854t_nor_flash); 132 platform_device_register(&wnr854t_nor_flash);
133} 133}
134 134
diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
index 2c5408e2e689..fae684bc54f2 100644
--- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c
+++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
@@ -213,8 +213,8 @@ static void __init wrt350n_v2_init(void)
213 orion5x_eth_switch_init(&wrt350n_v2_switch_plat_data, NO_IRQ); 213 orion5x_eth_switch_init(&wrt350n_v2_switch_plat_data, NO_IRQ);
214 orion5x_uart0_init(); 214 orion5x_uart0_init();
215 215
216 orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE, 216 mvebu_mbus_add_window("devbus-boot", WRT350N_V2_NOR_BOOT_BASE,
217 WRT350N_V2_NOR_BOOT_SIZE); 217 WRT350N_V2_NOR_BOOT_SIZE);
218 platform_device_register(&wrt350n_v2_nor_flash); 218 platform_device_register(&wrt350n_v2_nor_flash);
219 platform_device_register(&wrt350n_v2_leds); 219 platform_device_register(&wrt350n_v2_leds);
220 platform_device_register(&wrt350n_v2_button_device); 220 platform_device_register(&wrt350n_v2_button_device);
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
index 7d86bfbb5b06..31d5cd4d9787 100644
--- a/arch/arm/mach-shmobile/clock-r8a7779.c
+++ b/arch/arm/mach-shmobile/clock-r8a7779.c
@@ -26,6 +26,25 @@
26#include <mach/clock.h> 26#include <mach/clock.h>
27#include <mach/common.h> 27#include <mach/common.h>
28 28
29/*
30 * MD1 = 1 MD1 = 0
31 * (PLLA = 1500) (PLLA = 1600)
32 * (MHz) (MHz)
33 *------------------------------------------------+--------------------
34 * clkz 1000 (2/3) 800 (1/2)
35 * clkzs 250 (1/6) 200 (1/8)
36 * clki 750 (1/2) 800 (1/2)
37 * clks 250 (1/6) 200 (1/8)
38 * clks1 125 (1/12) 100 (1/16)
39 * clks3 187.5 (1/8) 200 (1/8)
40 * clks4 93.7 (1/16) 100 (1/16)
41 * clkp 62.5 (1/24) 50 (1/32)
42 * clkg 62.5 (1/24) 66.6 (1/24)
43 * clkb, CLKOUT
44 * (MD2 = 0) 62.5 (1/24) 66.6 (1/24)
45 * (MD2 = 1) 41.6 (1/36) 50 (1/32)
46*/
47
29#define MD(nr) BIT(nr) 48#define MD(nr) BIT(nr)
30 49
31#define FRQMR IOMEM(0xffc80014) 50#define FRQMR IOMEM(0xffc80014)
@@ -93,7 +112,7 @@ static struct clk *main_clks[] = {
93}; 112};
94 113
95enum { MSTP323, MSTP322, MSTP321, MSTP320, 114enum { MSTP323, MSTP322, MSTP321, MSTP320,
96 MSTP115, 115 MSTP115, MSTP114,
97 MSTP103, MSTP101, MSTP100, 116 MSTP103, MSTP101, MSTP100,
98 MSTP030, 117 MSTP030,
99 MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, 118 MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
@@ -107,6 +126,7 @@ static struct clk mstp_clks[MSTP_NR] = {
107 [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */ 126 [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */
108 [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */ 127 [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */
109 [MSTP115] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 15, 0), /* SATA */ 128 [MSTP115] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 15, 0), /* SATA */
129 [MSTP114] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 14, 0), /* Ether */
110 [MSTP103] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 3, 0), /* DU */ 130 [MSTP103] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 3, 0), /* DU */
111 [MSTP101] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 1, 0), /* USB2 */ 131 [MSTP101] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 1, 0), /* USB2 */
112 [MSTP100] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 0, 0), /* USB0/1 */ 132 [MSTP100] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 0, 0), /* USB0/1 */
@@ -143,6 +163,7 @@ static struct clk_lookup lookups[] = {
143 /* MSTP32 clocks */ 163 /* MSTP32 clocks */
144 CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */ 164 CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */
145 CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */ 165 CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */
166 CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP114]), /* Ether */
146 CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */ 167 CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */
147 CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */ 168 CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */
148 CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ 169 CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h
index 945299ed1638..188b295938a5 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7779.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h
@@ -3,6 +3,7 @@
3 3
4#include <linux/sh_clk.h> 4#include <linux/sh_clk.h>
5#include <linux/pm_domain.h> 5#include <linux/pm_domain.h>
6#include <linux/sh_eth.h>
6 7
7struct platform_device; 8struct platform_device;
8 9
@@ -31,6 +32,7 @@ extern void r8a7779_earlytimer_init(void);
31extern void r8a7779_add_early_devices(void); 32extern void r8a7779_add_early_devices(void);
32extern void r8a7779_add_standard_devices(void); 33extern void r8a7779_add_standard_devices(void);
33extern void r8a7779_add_standard_devices_dt(void); 34extern void r8a7779_add_standard_devices_dt(void);
35extern void r8a7779_add_ether_device(struct sh_eth_plat_data *pdata);
34extern void r8a7779_clock_init(void); 36extern void r8a7779_clock_init(void);
35extern void r8a7779_pinmux_init(void); 37extern void r8a7779_pinmux_init(void);
36extern void r8a7779_pm_init(void); 38extern void r8a7779_pm_init(void);
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index a460ba3dedcb..b0b394842ea5 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -1,8 +1,9 @@
1/* 1/*
2 * r8a7779 processor support 2 * r8a7779 processor support
3 * 3 *
4 * Copyright (C) 2011 Renesas Solutions Corp. 4 * Copyright (C) 2011, 2013 Renesas Solutions Corp.
5 * Copyright (C) 2011 Magnus Damm 5 * Copyright (C) 2011 Magnus Damm
6 * Copyright (C) 2013 Cogent Embedded, Inc.
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -393,6 +394,18 @@ static struct platform_device sata_device = {
393 }, 394 },
394}; 395};
395 396
397/* Ether */
398static struct resource ether_resources[] = {
399 {
400 .start = 0xfde00000,
401 .end = 0xfde003ff,
402 .flags = IORESOURCE_MEM,
403 }, {
404 .start = gic_iid(0xb4),
405 .flags = IORESOURCE_IRQ,
406 },
407};
408
396static struct platform_device *r8a7779_devices_dt[] __initdata = { 409static struct platform_device *r8a7779_devices_dt[] __initdata = {
397 &scif0_device, 410 &scif0_device,
398 &scif1_device, 411 &scif1_device,
@@ -428,6 +441,14 @@ void __init r8a7779_add_standard_devices(void)
428 ARRAY_SIZE(r8a7779_late_devices)); 441 ARRAY_SIZE(r8a7779_late_devices));
429} 442}
430 443
444void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata)
445{
446 platform_device_register_resndata(&platform_bus, "sh_eth", -1,
447 ether_resources,
448 ARRAY_SIZE(ether_resources),
449 pdata, sizeof(*pdata));
450}
451
431/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ 452/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
432void __init __weak r8a7779_register_twd(void) { } 453void __init __weak r8a7779_register_twd(void) { }
433 454
diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
index cf3226b041f5..c1d61f281e68 100644
--- a/arch/arm/mach-zynq/Kconfig
+++ b/arch/arm/mach-zynq/Kconfig
@@ -10,6 +10,7 @@ config ARCH_ZYNQ
10 select ICST 10 select ICST
11 select MIGHT_HAVE_CACHE_L2X0 11 select MIGHT_HAVE_CACHE_L2X0
12 select USE_OF 12 select USE_OF
13 select HAVE_SMP
13 select SPARSE_IRQ 14 select SPARSE_IRQ
14 select CADENCE_TTC_TIMER 15 select CADENCE_TTC_TIMER
15 help 16 help
diff --git a/arch/arm/mach-zynq/Makefile b/arch/arm/mach-zynq/Makefile
index 320faedeb484..1b25d92ebf22 100644
--- a/arch/arm/mach-zynq/Makefile
+++ b/arch/arm/mach-zynq/Makefile
@@ -3,4 +3,8 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := common.o 6obj-y := common.o slcr.o
7CFLAGS_REMOVE_hotplug.o =-march=armv6k
8CFLAGS_hotplug.o =-Wa,-march=armv7-a -mcpu=cortex-a9
9obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
10obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
index 68e0907de5d0..5bfe7035b73d 100644
--- a/arch/arm/mach-zynq/common.c
+++ b/arch/arm/mach-zynq/common.c
@@ -33,20 +33,23 @@
33#include <asm/mach-types.h> 33#include <asm/mach-types.h>
34#include <asm/page.h> 34#include <asm/page.h>
35#include <asm/pgtable.h> 35#include <asm/pgtable.h>
36#include <asm/smp_scu.h>
36#include <asm/hardware/cache-l2x0.h> 37#include <asm/hardware/cache-l2x0.h>
37 38
38#include "common.h" 39#include "common.h"
39 40
41void __iomem *zynq_scu_base;
42
40static struct of_device_id zynq_of_bus_ids[] __initdata = { 43static struct of_device_id zynq_of_bus_ids[] __initdata = {
41 { .compatible = "simple-bus", }, 44 { .compatible = "simple-bus", },
42 {} 45 {}
43}; 46};
44 47
45/** 48/**
46 * xilinx_init_machine() - System specific initialization, intended to be 49 * zynq_init_machine - System specific initialization, intended to be
47 * called from board specific initialization. 50 * called from board specific initialization.
48 */ 51 */
49static void __init xilinx_init_machine(void) 52static void __init zynq_init_machine(void)
50{ 53{
51 /* 54 /*
52 * 64KB way size, 8-way associativity, parity disabled 55 * 64KB way size, 8-way associativity, parity disabled
@@ -56,50 +59,56 @@ static void __init xilinx_init_machine(void)
56 of_platform_bus_probe(NULL, zynq_of_bus_ids, NULL); 59 of_platform_bus_probe(NULL, zynq_of_bus_ids, NULL);
57} 60}
58 61
59#define SCU_PERIPH_PHYS 0xF8F00000 62static void __init zynq_timer_init(void)
60#define SCU_PERIPH_SIZE SZ_8K 63{
61#define SCU_PERIPH_VIRT (VMALLOC_END - SCU_PERIPH_SIZE) 64 zynq_slcr_init();
65 clocksource_of_init();
66}
62 67
63static struct map_desc scu_desc __initdata = { 68static struct map_desc zynq_cortex_a9_scu_map __initdata = {
64 .virtual = SCU_PERIPH_VIRT, 69 .length = SZ_256,
65 .pfn = __phys_to_pfn(SCU_PERIPH_PHYS), 70 .type = MT_DEVICE,
66 .length = SCU_PERIPH_SIZE,
67 .type = MT_DEVICE,
68}; 71};
69 72
70static void __init xilinx_zynq_timer_init(void) 73static void __init zynq_scu_map_io(void)
71{ 74{
72 struct device_node *np; 75 unsigned long base;
73 void __iomem *slcr;
74
75 np = of_find_compatible_node(NULL, NULL, "xlnx,zynq-slcr");
76 slcr = of_iomap(np, 0);
77 WARN_ON(!slcr);
78 76
79 xilinx_zynq_clocks_init(slcr); 77 base = scu_a9_get_base();
80 78 zynq_cortex_a9_scu_map.pfn = __phys_to_pfn(base);
81 clocksource_of_init(); 79 /* Expected address is in vmalloc area that's why simple assign here */
80 zynq_cortex_a9_scu_map.virtual = base;
81 iotable_init(&zynq_cortex_a9_scu_map, 1);
82 zynq_scu_base = (void __iomem *)base;
83 BUG_ON(!zynq_scu_base);
82} 84}
83 85
84/** 86/**
85 * xilinx_map_io() - Create memory mappings needed for early I/O. 87 * zynq_map_io - Create memory mappings needed for early I/O.
86 */ 88 */
87static void __init xilinx_map_io(void) 89static void __init zynq_map_io(void)
88{ 90{
89 debug_ll_io_init(); 91 debug_ll_io_init();
90 iotable_init(&scu_desc, 1); 92 zynq_scu_map_io();
93}
94
95static void zynq_system_reset(char mode, const char *cmd)
96{
97 zynq_slcr_system_reset();
91} 98}
92 99
93static const char *xilinx_dt_match[] = { 100static const char * const zynq_dt_match[] = {
94 "xlnx,zynq-zc702", 101 "xlnx,zynq-zc702",
95 "xlnx,zynq-7000", 102 "xlnx,zynq-7000",
96 NULL 103 NULL
97}; 104};
98 105
99MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform") 106MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform")
100 .map_io = xilinx_map_io, 107 .smp = smp_ops(zynq_smp_ops),
108 .map_io = zynq_map_io,
101 .init_irq = irqchip_init, 109 .init_irq = irqchip_init,
102 .init_machine = xilinx_init_machine, 110 .init_machine = zynq_init_machine,
103 .init_time = xilinx_zynq_timer_init, 111 .init_time = zynq_timer_init,
104 .dt_compat = xilinx_dt_match, 112 .dt_compat = zynq_dt_match,
113 .restart = zynq_system_reset,
105MACHINE_END 114MACHINE_END
diff --git a/arch/arm/mach-zynq/common.h b/arch/arm/mach-zynq/common.h
index 5050bb10bb12..fbbd0e21c404 100644
--- a/arch/arm/mach-zynq/common.h
+++ b/arch/arm/mach-zynq/common.h
@@ -17,4 +17,24 @@
17#ifndef __MACH_ZYNQ_COMMON_H__ 17#ifndef __MACH_ZYNQ_COMMON_H__
18#define __MACH_ZYNQ_COMMON_H__ 18#define __MACH_ZYNQ_COMMON_H__
19 19
20extern int zynq_slcr_init(void);
21extern void zynq_slcr_system_reset(void);
22extern void zynq_slcr_cpu_stop(int cpu);
23extern void zynq_slcr_cpu_start(int cpu);
24
25#ifdef CONFIG_SMP
26extern void secondary_startup(void);
27extern char zynq_secondary_trampoline;
28extern char zynq_secondary_trampoline_jump;
29extern char zynq_secondary_trampoline_end;
30extern int __cpuinit zynq_cpun_start(u32 address, int cpu);
31extern struct smp_operations zynq_smp_ops __initdata;
32#endif
33
34extern void __iomem *zynq_slcr_base;
35extern void __iomem *zynq_scu_base;
36
37/* Hotplug */
38extern void zynq_platform_cpu_die(unsigned int cpu);
39
20#endif 40#endif
diff --git a/arch/arm/mach-zynq/headsmp.S b/arch/arm/mach-zynq/headsmp.S
new file mode 100644
index 000000000000..d183cd234a9b
--- /dev/null
+++ b/arch/arm/mach-zynq/headsmp.S
@@ -0,0 +1,24 @@
1/*
2 * Copyright (c) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de>
3 * Copyright (c) 2012-2013 Xilinx
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#include <linux/linkage.h>
10#include <linux/init.h>
11
12 __CPUINIT
13
14ENTRY(zynq_secondary_trampoline)
15 ldr r0, [pc]
16 bx r0
17.globl zynq_secondary_trampoline_jump
18zynq_secondary_trampoline_jump:
19 /* Space for jumping address */
20 .word /* cpu 1 */
21.globl zynq_secondary_trampoline_end
22zynq_secondary_trampoline_end:
23
24ENDPROC(zynq_secondary_trampoline)
diff --git a/arch/arm/mach-zynq/hotplug.c b/arch/arm/mach-zynq/hotplug.c
new file mode 100644
index 000000000000..c89672bd1de2
--- /dev/null
+++ b/arch/arm/mach-zynq/hotplug.c
@@ -0,0 +1,104 @@
1/*
2 * Copyright (C) 2012-2013 Xilinx
3 *
4 * based on linux/arch/arm/mach-realview/hotplug.c
5 *
6 * Copyright (C) 2002 ARM Ltd.
7 * All Rights Reserved
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#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/smp.h>
16
17#include <asm/cacheflush.h>
18#include <asm/cp15.h>
19#include "common.h"
20
21static inline void zynq_cpu_enter_lowpower(void)
22{
23 unsigned int v;
24
25 flush_cache_all();
26 asm volatile(
27 " mcr p15, 0, %1, c7, c5, 0\n"
28 " dsb\n"
29 /*
30 * Turn off coherency
31 */
32 " mrc p15, 0, %0, c1, c0, 1\n"
33 " bic %0, %0, #0x40\n"
34 " mcr p15, 0, %0, c1, c0, 1\n"
35 " mrc p15, 0, %0, c1, c0, 0\n"
36 " bic %0, %0, %2\n"
37 " mcr p15, 0, %0, c1, c0, 0\n"
38 : "=&r" (v)
39 : "r" (0), "Ir" (CR_C)
40 : "cc");
41}
42
43static inline void zynq_cpu_leave_lowpower(void)
44{
45 unsigned int v;
46
47 asm volatile(
48 " mrc p15, 0, %0, c1, c0, 0\n"
49 " orr %0, %0, %1\n"
50 " mcr p15, 0, %0, c1, c0, 0\n"
51 " mrc p15, 0, %0, c1, c0, 1\n"
52 " orr %0, %0, #0x40\n"
53 " mcr p15, 0, %0, c1, c0, 1\n"
54 : "=&r" (v)
55 : "Ir" (CR_C)
56 : "cc");
57}
58
59static inline void zynq_platform_do_lowpower(unsigned int cpu, int *spurious)
60{
61 /*
62 * there is no power-control hardware on this platform, so all
63 * we can do is put the core into WFI; this is safe as the calling
64 * code will have already disabled interrupts
65 */
66 for (;;) {
67 dsb();
68 wfi();
69
70 /*
71 * Getting here, means that we have come out of WFI without
72 * having been woken up - this shouldn't happen
73 *
74 * Just note it happening - when we're woken, we can report
75 * its occurrence.
76 */
77 (*spurious)++;
78 }
79}
80
81/*
82 * platform-specific code to shutdown a CPU
83 *
84 * Called with IRQs disabled
85 */
86void zynq_platform_cpu_die(unsigned int cpu)
87{
88 int spurious = 0;
89
90 /*
91 * we're ready for shutdown now, so do it
92 */
93 zynq_cpu_enter_lowpower();
94 zynq_platform_do_lowpower(cpu, &spurious);
95
96 /*
97 * bring this CPU back into the world of cache
98 * coherency, and then restore interrupts
99 */
100 zynq_cpu_leave_lowpower();
101
102 if (spurious)
103 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
104}
diff --git a/arch/arm/mach-zynq/platsmp.c b/arch/arm/mach-zynq/platsmp.c
new file mode 100644
index 000000000000..5fc167e07619
--- /dev/null
+++ b/arch/arm/mach-zynq/platsmp.c
@@ -0,0 +1,136 @@
1/*
2 * This file contains Xilinx specific SMP code, used to start up
3 * the second processor.
4 *
5 * Copyright (C) 2011-2013 Xilinx
6 *
7 * based on linux/arch/arm/mach-realview/platsmp.c
8 *
9 * Copyright (C) 2002 ARM Ltd.
10 *
11 * This software is licensed under the terms of the GNU General Public
12 * License version 2, as published by the Free Software Foundation, and
13 * may be copied, distributed, and modified under those terms.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
20
21#include <linux/export.h>
22#include <linux/jiffies.h>
23#include <linux/init.h>
24#include <linux/io.h>
25#include <asm/cacheflush.h>
26#include <asm/smp_scu.h>
27#include <linux/irqchip/arm-gic.h>
28#include "common.h"
29
30/*
31 * Store number of cores in the system
32 * Because of scu_get_core_count() must be in __init section and can't
33 * be called from zynq_cpun_start() because it is in __cpuinit section.
34 */
35static int ncores;
36
37int __cpuinit zynq_cpun_start(u32 address, int cpu)
38{
39 u32 trampoline_code_size = &zynq_secondary_trampoline_end -
40 &zynq_secondary_trampoline;
41
42 if (cpu > ncores) {
43 pr_warn("CPU No. is not available in the system\n");
44 return -1;
45 }
46
47 /* MS: Expectation that SLCR are directly map and accessible */
48 /* Not possible to jump to non aligned address */
49 if (!(address & 3) && (!address || (address >= trampoline_code_size))) {
50 /* Store pointer to ioremap area which points to address 0x0 */
51 static u8 __iomem *zero;
52 u32 trampoline_size = &zynq_secondary_trampoline_jump -
53 &zynq_secondary_trampoline;
54
55 zynq_slcr_cpu_stop(cpu);
56
57 if (__pa(PAGE_OFFSET)) {
58 zero = ioremap(0, trampoline_code_size);
59 if (!zero) {
60 pr_warn("BOOTUP jump vectors not accessible\n");
61 return -1;
62 }
63 } else {
64 zero = (__force u8 __iomem *)PAGE_OFFSET;
65 }
66
67 /*
68 * This is elegant way how to jump to any address
69 * 0x0: Load address at 0x8 to r0
70 * 0x4: Jump by mov instruction
71 * 0x8: Jumping address
72 */
73 memcpy((__force void *)zero, &zynq_secondary_trampoline,
74 trampoline_size);
75 writel(address, zero + trampoline_size);
76
77 flush_cache_all();
78 outer_flush_range(0, trampoline_code_size);
79 smp_wmb();
80
81 if (__pa(PAGE_OFFSET))
82 iounmap(zero);
83
84 zynq_slcr_cpu_start(cpu);
85
86 return 0;
87 }
88
89 pr_warn("Can't start CPU%d: Wrong starting address %x\n", cpu, address);
90
91 return -1;
92}
93EXPORT_SYMBOL(zynq_cpun_start);
94
95static int __cpuinit zynq_boot_secondary(unsigned int cpu,
96 struct task_struct *idle)
97{
98 return zynq_cpun_start(virt_to_phys(secondary_startup), cpu);
99}
100
101/*
102 * Initialise the CPU possible map early - this describes the CPUs
103 * which may be present or become present in the system.
104 */
105static void __init zynq_smp_init_cpus(void)
106{
107 int i;
108
109 ncores = scu_get_core_count(zynq_scu_base);
110
111 for (i = 0; i < ncores && i < CONFIG_NR_CPUS; i++)
112 set_cpu_possible(i, true);
113}
114
115static void __init zynq_smp_prepare_cpus(unsigned int max_cpus)
116{
117 int i;
118
119 /*
120 * Initialise the present map, which describes the set of CPUs
121 * actually populated at the present time.
122 */
123 for (i = 0; i < max_cpus; i++)
124 set_cpu_present(i, true);
125
126 scu_enable(zynq_scu_base);
127}
128
129struct smp_operations zynq_smp_ops __initdata = {
130 .smp_init_cpus = zynq_smp_init_cpus,
131 .smp_prepare_cpus = zynq_smp_prepare_cpus,
132 .smp_boot_secondary = zynq_boot_secondary,
133#ifdef CONFIG_HOTPLUG_CPU
134 .cpu_die = zynq_platform_cpu_die,
135#endif
136};
diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c
new file mode 100644
index 000000000000..c70969b9c258
--- /dev/null
+++ b/arch/arm/mach-zynq/slcr.c
@@ -0,0 +1,125 @@
1/*
2 * Xilinx SLCR driver
3 *
4 * Copyright (c) 2011-2013 Xilinx Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * You should have received a copy of the GNU General Public
12 * License along with this program; if not, write to the Free
13 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
14 * 02139, USA.
15 */
16
17#include <linux/export.h>
18#include <linux/io.h>
19#include <linux/fs.h>
20#include <linux/interrupt.h>
21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/of_address.h>
25#include <linux/uaccess.h>
26#include <linux/platform_device.h>
27#include <linux/slab.h>
28#include <linux/string.h>
29#include <linux/clk/zynq.h>
30#include "common.h"
31
32#define SLCR_UNLOCK_MAGIC 0xDF0D
33#define SLCR_UNLOCK 0x8 /* SCLR unlock register */
34
35#define SLCR_PS_RST_CTRL_OFFSET 0x200 /* PS Software Reset Control */
36
37#define SLCR_A9_CPU_CLKSTOP 0x10
38#define SLCR_A9_CPU_RST 0x1
39
40#define SLCR_A9_CPU_RST_CTRL 0x244 /* CPU Software Reset Control */
41#define SLCR_REBOOT_STATUS 0x258 /* PS Reboot Status */
42
43void __iomem *zynq_slcr_base;
44
45/**
46 * zynq_slcr_system_reset - Reset the entire system.
47 */
48void zynq_slcr_system_reset(void)
49{
50 u32 reboot;
51
52 /*
53 * Unlock the SLCR then reset the system.
54 * Note that this seems to require raw i/o
55 * functions or there's a lockup?
56 */
57 writel(SLCR_UNLOCK_MAGIC, zynq_slcr_base + SLCR_UNLOCK);
58
59 /*
60 * Clear 0x0F000000 bits of reboot status register to workaround
61 * the FSBL not loading the bitstream after soft-reboot
62 * This is a temporary solution until we know more.
63 */
64 reboot = readl(zynq_slcr_base + SLCR_REBOOT_STATUS);
65 writel(reboot & 0xF0FFFFFF, zynq_slcr_base + SLCR_REBOOT_STATUS);
66 writel(1, zynq_slcr_base + SLCR_PS_RST_CTRL_OFFSET);
67}
68
69/**
70 * zynq_slcr_cpu_start - Start cpu
71 * @cpu: cpu number
72 */
73void zynq_slcr_cpu_start(int cpu)
74{
75 /* enable CPUn */
76 writel(SLCR_A9_CPU_CLKSTOP << cpu,
77 zynq_slcr_base + SLCR_A9_CPU_RST_CTRL);
78 /* enable CLK for CPUn */
79 writel(0x0 << cpu, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL);
80}
81
82/**
83 * zynq_slcr_cpu_stop - Stop cpu
84 * @cpu: cpu number
85 */
86void zynq_slcr_cpu_stop(int cpu)
87{
88 /* stop CLK and reset CPUn */
89 writel((SLCR_A9_CPU_CLKSTOP | SLCR_A9_CPU_RST) << cpu,
90 zynq_slcr_base + SLCR_A9_CPU_RST_CTRL);
91}
92
93/**
94 * zynq_slcr_init
95 * Returns 0 on success, negative errno otherwise.
96 *
97 * Called early during boot from platform code to remap SLCR area.
98 */
99int __init zynq_slcr_init(void)
100{
101 struct device_node *np;
102
103 np = of_find_compatible_node(NULL, NULL, "xlnx,zynq-slcr");
104 if (!np) {
105 pr_err("%s: no slcr node found\n", __func__);
106 BUG();
107 }
108
109 zynq_slcr_base = of_iomap(np, 0);
110 if (!zynq_slcr_base) {
111 pr_err("%s: Unable to map I/O memory\n", __func__);
112 BUG();
113 }
114
115 /* unlock the SLCR so that registers can be changed */
116 writel(SLCR_UNLOCK_MAGIC, zynq_slcr_base + SLCR_UNLOCK);
117
118 pr_info("%s mapped to %p\n", np->name, zynq_slcr_base);
119
120 xilinx_zynq_clocks_init(zynq_slcr_base);
121
122 of_node_put(np);
123
124 return 0;
125}
diff --git a/arch/arm/plat-orion/Makefile b/arch/arm/plat-orion/Makefile
index ad97400ba3ad..2eca54b65906 100644
--- a/arch/arm/plat-orion/Makefile
+++ b/arch/arm/plat-orion/Makefile
@@ -3,12 +3,6 @@
3# 3#
4ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include 4ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
5 5
6obj-$(CONFIG_ARCH_MVEBU) += addr-map.o
7obj-$(CONFIG_ARCH_KIRKWOOD) += addr-map.o
8obj-$(CONFIG_ARCH_DOVE) += addr-map.o
9obj-$(CONFIG_ARCH_ORION5X) += addr-map.o
10obj-$(CONFIG_ARCH_MV78XX0) += addr-map.o
11
12orion-gpio-$(CONFIG_GENERIC_GPIO) += gpio.o 6orion-gpio-$(CONFIG_GENERIC_GPIO) += gpio.o
13obj-$(CONFIG_PLAT_ORION_LEGACY) += irq.o pcie.o time.o common.o mpp.o 7obj-$(CONFIG_PLAT_ORION_LEGACY) += irq.o pcie.o time.o common.o mpp.o
14obj-$(CONFIG_PLAT_ORION_LEGACY) += $(orion-gpio-y) 8obj-$(CONFIG_PLAT_ORION_LEGACY) += $(orion-gpio-y)
diff --git a/arch/arm/plat-orion/addr-map.c b/arch/arm/plat-orion/addr-map.c
deleted file mode 100644
index 807ac8e5cbc0..000000000000
--- a/arch/arm/plat-orion/addr-map.c
+++ /dev/null
@@ -1,178 +0,0 @@
1/*
2 * arch/arm/plat-orion/addr-map.c
3 *
4 * Address map functions for Marvell Orion based SoCs
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/mbus.h>
15#include <linux/io.h>
16#include <plat/addr-map.h>
17
18struct mbus_dram_target_info orion_mbus_dram_info;
19
20const struct mbus_dram_target_info *mv_mbus_dram_info(void)
21{
22 return &orion_mbus_dram_info;
23}
24EXPORT_SYMBOL_GPL(mv_mbus_dram_info);
25
26/*
27 * DDR target is the same on all Orion platforms.
28 */
29#define TARGET_DDR 0
30
31/*
32 * Helpers to get DDR bank info
33 */
34#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3))
35#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3))
36
37/*
38 * CPU Address Decode Windows registers
39 */
40#define WIN_CTRL_OFF 0x0000
41#define WIN_BASE_OFF 0x0004
42#define WIN_REMAP_LO_OFF 0x0008
43#define WIN_REMAP_HI_OFF 0x000c
44
45#define ATTR_HW_COHERENCY (0x1 << 4)
46
47/*
48 * Default implementation
49 */
50static void __init __iomem *
51orion_win_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
52{
53 return cfg->bridge_virt_base + (win << 4);
54}
55
56/*
57 * Default implementation
58 */
59static int __init orion_cpu_win_can_remap(const struct orion_addr_map_cfg *cfg,
60 const int win)
61{
62 if (win < cfg->remappable_wins)
63 return 1;
64
65 return 0;
66}
67
68void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg,
69 const int win, const u32 base,
70 const u32 size, const u8 target,
71 const u8 attr, const int remap)
72{
73 void __iomem *addr = cfg->win_cfg_base(cfg, win);
74 u32 ctrl, base_high, remap_addr;
75
76 if (win >= cfg->num_wins) {
77 printk(KERN_ERR "setup_cpu_win: trying to allocate window "
78 "%d when only %d allowed\n", win, cfg->num_wins);
79 }
80
81 base_high = base & 0xffff0000;
82 ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
83
84 writel(base_high, addr + WIN_BASE_OFF);
85 writel(ctrl, addr + WIN_CTRL_OFF);
86 if (cfg->cpu_win_can_remap(cfg, win)) {
87 if (remap < 0)
88 remap_addr = base;
89 else
90 remap_addr = remap;
91 writel(remap_addr & 0xffff0000, addr + WIN_REMAP_LO_OFF);
92 writel(0, addr + WIN_REMAP_HI_OFF);
93 }
94}
95
96/*
97 * Configure a number of windows.
98 */
99static void __init orion_setup_cpu_wins(const struct orion_addr_map_cfg * cfg,
100 const struct orion_addr_map_info *info)
101{
102 while (info->win != -1) {
103 orion_setup_cpu_win(cfg, info->win, info->base, info->size,
104 info->target, info->attr, info->remap);
105 info++;
106 }
107}
108
109static void __init orion_disable_wins(const struct orion_addr_map_cfg * cfg)
110{
111 void __iomem *addr;
112 int i;
113
114 for (i = 0; i < cfg->num_wins; i++) {
115 addr = cfg->win_cfg_base(cfg, i);
116
117 writel(0, addr + WIN_BASE_OFF);
118 writel(0, addr + WIN_CTRL_OFF);
119 if (cfg->cpu_win_can_remap(cfg, i)) {
120 writel(0, addr + WIN_REMAP_LO_OFF);
121 writel(0, addr + WIN_REMAP_HI_OFF);
122 }
123 }
124}
125
126/*
127 * Disable, clear and configure windows.
128 */
129void __init orion_config_wins(struct orion_addr_map_cfg * cfg,
130 const struct orion_addr_map_info *info)
131{
132 if (!cfg->cpu_win_can_remap)
133 cfg->cpu_win_can_remap = orion_cpu_win_can_remap;
134
135 if (!cfg->win_cfg_base)
136 cfg->win_cfg_base = orion_win_cfg_base;
137
138 orion_disable_wins(cfg);
139
140 if (info)
141 orion_setup_cpu_wins(cfg, info);
142}
143
144/*
145 * Setup MBUS dram target info.
146 */
147void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
148 const void __iomem *ddr_window_cpu_base)
149{
150 int i;
151 int cs;
152
153 orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
154
155 for (i = 0, cs = 0; i < 4; i++) {
156 u32 base = readl(ddr_window_cpu_base + DDR_BASE_CS_OFF(i));
157 u32 size = readl(ddr_window_cpu_base + DDR_SIZE_CS_OFF(i));
158
159 /*
160 * We only take care of entries for which the chip
161 * select is enabled, and that don't have high base
162 * address bits set (devices can only access the first
163 * 32 bits of the memory).
164 */
165 if ((size & 1) && !(base & 0xF)) {
166 struct mbus_dram_window *w;
167
168 w = &orion_mbus_dram_info.cs[cs++];
169 w->cs_index = i;
170 w->mbus_attr = 0xf & ~(1 << i);
171 if (cfg->hw_io_coherency)
172 w->mbus_attr |= ATTR_HW_COHERENCY;
173 w->base = base & 0xffff0000;
174 w->size = (size | 0x0000ffff) + 1;
175 }
176 }
177 orion_mbus_dram_info.num_cs = cs;
178}
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
index c29ee7ea200b..e39c2ba6e2fb 100644
--- a/arch/arm/plat-orion/gpio.c
+++ b/arch/arm/plat-orion/gpio.c
@@ -439,6 +439,64 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
439 } 439 }
440} 440}
441 441
442#ifdef CONFIG_DEBUG_FS
443#include <linux/seq_file.h>
444
445static void orion_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
446{
447 struct orion_gpio_chip *ochip =
448 container_of(chip, struct orion_gpio_chip, chip);
449 u32 out, io_conf, blink, in_pol, data_in, cause, edg_msk, lvl_msk;
450 int i;
451
452 out = readl_relaxed(GPIO_OUT(ochip));
453 io_conf = readl_relaxed(GPIO_IO_CONF(ochip));
454 blink = readl_relaxed(GPIO_BLINK_EN(ochip));
455 in_pol = readl_relaxed(GPIO_IN_POL(ochip));
456 data_in = readl_relaxed(GPIO_DATA_IN(ochip));
457 cause = readl_relaxed(GPIO_EDGE_CAUSE(ochip));
458 edg_msk = readl_relaxed(GPIO_EDGE_MASK(ochip));
459 lvl_msk = readl_relaxed(GPIO_LEVEL_MASK(ochip));
460
461 for (i = 0; i < chip->ngpio; i++) {
462 const char *label;
463 u32 msk;
464 bool is_out;
465
466 label = gpiochip_is_requested(chip, i);
467 if (!label)
468 continue;
469
470 msk = 1 << i;
471 is_out = !(io_conf & msk);
472
473 seq_printf(s, " gpio-%-3d (%-20.20s)", chip->base + i, label);
474
475 if (is_out) {
476 seq_printf(s, " out %s %s\n",
477 out & msk ? "hi" : "lo",
478 blink & msk ? "(blink )" : "");
479 continue;
480 }
481
482 seq_printf(s, " in %s (act %s) - IRQ",
483 (data_in ^ in_pol) & msk ? "hi" : "lo",
484 in_pol & msk ? "lo" : "hi");
485 if (!((edg_msk | lvl_msk) & msk)) {
486 seq_printf(s, " disabled\n");
487 continue;
488 }
489 if (edg_msk & msk)
490 seq_printf(s, " edge ");
491 if (lvl_msk & msk)
492 seq_printf(s, " level");
493 seq_printf(s, " (%s)\n", cause & msk ? "pending" : "clear ");
494 }
495}
496#else
497#define orion_gpio_dbg_show NULL
498#endif
499
442void __init orion_gpio_init(struct device_node *np, 500void __init orion_gpio_init(struct device_node *np,
443 int gpio_base, int ngpio, 501 int gpio_base, int ngpio,
444 void __iomem *base, int mask_offset, 502 void __iomem *base, int mask_offset,
@@ -471,6 +529,7 @@ void __init orion_gpio_init(struct device_node *np,
471#ifdef CONFIG_OF 529#ifdef CONFIG_OF
472 ochip->chip.of_node = np; 530 ochip->chip.of_node = np;
473#endif 531#endif
532 ochip->chip.dbg_show = orion_gpio_dbg_show;
474 533
475 spin_lock_init(&ochip->lock); 534 spin_lock_init(&ochip->lock);
476 ochip->base = (void __iomem *)base; 535 ochip->base = (void __iomem *)base;
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 0f51ed687dc8..b05ecab915c4 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -4,6 +4,13 @@
4 4
5menu "Bus devices" 5menu "Bus devices"
6 6
7config MVEBU_MBUS
8 bool
9 depends on PLAT_ORION
10 help
11 Driver needed for the MBus configuration on Marvell EBU SoCs
12 (Kirkwood, Dove, Orion5x, MV78XX0 and Armada 370/XP).
13
7config OMAP_OCP2SCP 14config OMAP_OCP2SCP
8 tristate "OMAP OCP2SCP DRIVER" 15 tristate "OMAP OCP2SCP DRIVER"
9 depends on ARCH_OMAP2PLUS 16 depends on ARCH_OMAP2PLUS
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 45d997c85453..3c7b53c12091 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -2,6 +2,7 @@
2# Makefile for the bus drivers. 2# Makefile for the bus drivers.
3# 3#
4 4
5obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o
5obj-$(CONFIG_OMAP_OCP2SCP) += omap-ocp2scp.o 6obj-$(CONFIG_OMAP_OCP2SCP) += omap-ocp2scp.o
6 7
7# Interconnect bus driver for OMAP SoCs. 8# Interconnect bus driver for OMAP SoCs.
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c
new file mode 100644
index 000000000000..8740f46b4d0d
--- /dev/null
+++ b/drivers/bus/mvebu-mbus.c
@@ -0,0 +1,870 @@
1/*
2 * Address map functions for Marvell EBU SoCs (Kirkwood, Armada
3 * 370/XP, Dove, Orion5x and MV78xx0)
4 *
5 * This file is licensed under the terms of the GNU General Public
6 * License version 2. This program is licensed "as is" without any
7 * warranty of any kind, whether express or implied.
8 *
9 * The Marvell EBU SoCs have a configurable physical address space:
10 * the physical address at which certain devices (PCIe, NOR, NAND,
11 * etc.) sit can be configured. The configuration takes place through
12 * two sets of registers:
13 *
14 * - One to configure the access of the CPU to the devices. Depending
15 * on the families, there are between 8 and 20 configurable windows,
16 * each can be use to create a physical memory window that maps to a
17 * specific device. Devices are identified by a tuple (target,
18 * attribute).
19 *
20 * - One to configure the access to the CPU to the SDRAM. There are
21 * either 2 (for Dove) or 4 (for other families) windows to map the
22 * SDRAM into the physical address space.
23 *
24 * This driver:
25 *
26 * - Reads out the SDRAM address decoding windows at initialization
27 * time, and fills the mvebu_mbus_dram_info structure with these
28 * informations. The exported function mv_mbus_dram_info() allow
29 * device drivers to get those informations related to the SDRAM
30 * address decoding windows. This is because devices also have their
31 * own windows (configured through registers that are part of each
32 * device register space), and therefore the drivers for Marvell
33 * devices have to configure those device -> SDRAM windows to ensure
34 * that DMA works properly.
35 *
36 * - Provides an API for platform code or device drivers to
37 * dynamically add or remove address decoding windows for the CPU ->
38 * device accesses. This API is mvebu_mbus_add_window(),
39 * mvebu_mbus_add_window_remap_flags() and
40 * mvebu_mbus_del_window(). Since the (target, attribute) values
41 * differ from one SoC family to another, the API uses a 'const char
42 * *' string to identify devices, and this driver is responsible for
43 * knowing the mapping between the name of a device and its
44 * corresponding (target, attribute) in the current SoC family.
45 *
46 * - Provides a debugfs interface in /sys/kernel/debug/mvebu-mbus/ to
47 * see the list of CPU -> SDRAM windows and their configuration
48 * (file 'sdram') and the list of CPU -> devices windows and their
49 * configuration (file 'devices').
50 */
51
52#include <linux/kernel.h>
53#include <linux/module.h>
54#include <linux/init.h>
55#include <linux/mbus.h>
56#include <linux/io.h>
57#include <linux/ioport.h>
58#include <linux/of.h>
59#include <linux/of_address.h>
60#include <linux/debugfs.h>
61
62/*
63 * DDR target is the same on all platforms.
64 */
65#define TARGET_DDR 0
66
67/*
68 * CPU Address Decode Windows registers
69 */
70#define WIN_CTRL_OFF 0x0000
71#define WIN_CTRL_ENABLE BIT(0)
72#define WIN_CTRL_TGT_MASK 0xf0
73#define WIN_CTRL_TGT_SHIFT 4
74#define WIN_CTRL_ATTR_MASK 0xff00
75#define WIN_CTRL_ATTR_SHIFT 8
76#define WIN_CTRL_SIZE_MASK 0xffff0000
77#define WIN_CTRL_SIZE_SHIFT 16
78#define WIN_BASE_OFF 0x0004
79#define WIN_BASE_LOW 0xffff0000
80#define WIN_BASE_HIGH 0xf
81#define WIN_REMAP_LO_OFF 0x0008
82#define WIN_REMAP_LOW 0xffff0000
83#define WIN_REMAP_HI_OFF 0x000c
84
85#define ATTR_HW_COHERENCY (0x1 << 4)
86
87#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3))
88#define DDR_BASE_CS_HIGH_MASK 0xf
89#define DDR_BASE_CS_LOW_MASK 0xff000000
90#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3))
91#define DDR_SIZE_ENABLED BIT(0)
92#define DDR_SIZE_CS_MASK 0x1c
93#define DDR_SIZE_CS_SHIFT 2
94#define DDR_SIZE_MASK 0xff000000
95
96#define DOVE_DDR_BASE_CS_OFF(n) ((n) << 4)
97
98struct mvebu_mbus_mapping {
99 const char *name;
100 u8 target;
101 u8 attr;
102 u8 attrmask;
103};
104
105/*
106 * Masks used for the 'attrmask' field of mvebu_mbus_mapping. They
107 * allow to get the real attribute value, discarding the special bits
108 * used to select a PCI MEM region or a PCI WA region. This allows the
109 * debugfs code to reverse-match the name of a device from its
110 * target/attr values.
111 *
112 * For all devices except PCI, all bits of 'attr' must be
113 * considered. For most SoCs, only bit 3 should be ignored (it allows
114 * to select between PCI MEM and PCI I/O). On Orion5x however, there
115 * is the special bit 5 to select a PCI WA region.
116 */
117#define MAPDEF_NOMASK 0xff
118#define MAPDEF_PCIMASK 0xf7
119#define MAPDEF_ORIONPCIMASK 0xd7
120
121/* Macro used to define one mvebu_mbus_mapping entry */
122#define MAPDEF(__n, __t, __a, __m) \
123 { .name = __n, .target = __t, .attr = __a, .attrmask = __m }
124
125struct mvebu_mbus_state;
126
127struct mvebu_mbus_soc_data {
128 unsigned int num_wins;
129 unsigned int num_remappable_wins;
130 unsigned int (*win_cfg_offset)(const int win);
131 void (*setup_cpu_target)(struct mvebu_mbus_state *s);
132 int (*show_cpu_target)(struct mvebu_mbus_state *s,
133 struct seq_file *seq, void *v);
134 const struct mvebu_mbus_mapping *map;
135};
136
137struct mvebu_mbus_state {
138 void __iomem *mbuswins_base;
139 void __iomem *sdramwins_base;
140 struct dentry *debugfs_root;
141 struct dentry *debugfs_sdram;
142 struct dentry *debugfs_devs;
143 const struct mvebu_mbus_soc_data *soc;
144 int hw_io_coherency;
145};
146
147static struct mvebu_mbus_state mbus_state;
148
149static struct mbus_dram_target_info mvebu_mbus_dram_info;
150const struct mbus_dram_target_info *mv_mbus_dram_info(void)
151{
152 return &mvebu_mbus_dram_info;
153}
154EXPORT_SYMBOL_GPL(mv_mbus_dram_info);
155
156/*
157 * Functions to manipulate the address decoding windows
158 */
159
160static void mvebu_mbus_read_window(struct mvebu_mbus_state *mbus,
161 int win, int *enabled, u64 *base,
162 u32 *size, u8 *target, u8 *attr,
163 u64 *remap)
164{
165 void __iomem *addr = mbus->mbuswins_base +
166 mbus->soc->win_cfg_offset(win);
167 u32 basereg = readl(addr + WIN_BASE_OFF);
168 u32 ctrlreg = readl(addr + WIN_CTRL_OFF);
169
170 if (!(ctrlreg & WIN_CTRL_ENABLE)) {
171 *enabled = 0;
172 return;
173 }
174
175 *enabled = 1;
176 *base = ((u64)basereg & WIN_BASE_HIGH) << 32;
177 *base |= (basereg & WIN_BASE_LOW);
178 *size = (ctrlreg | ~WIN_CTRL_SIZE_MASK) + 1;
179
180 if (target)
181 *target = (ctrlreg & WIN_CTRL_TGT_MASK) >> WIN_CTRL_TGT_SHIFT;
182
183 if (attr)
184 *attr = (ctrlreg & WIN_CTRL_ATTR_MASK) >> WIN_CTRL_ATTR_SHIFT;
185
186 if (remap) {
187 if (win < mbus->soc->num_remappable_wins) {
188 u32 remap_low = readl(addr + WIN_REMAP_LO_OFF);
189 u32 remap_hi = readl(addr + WIN_REMAP_HI_OFF);
190 *remap = ((u64)remap_hi << 32) | remap_low;
191 } else
192 *remap = 0;
193 }
194}
195
196static void mvebu_mbus_disable_window(struct mvebu_mbus_state *mbus,
197 int win)
198{
199 void __iomem *addr;
200
201 addr = mbus->mbuswins_base + mbus->soc->win_cfg_offset(win);
202
203 writel(0, addr + WIN_BASE_OFF);
204 writel(0, addr + WIN_CTRL_OFF);
205 if (win < mbus->soc->num_remappable_wins) {
206 writel(0, addr + WIN_REMAP_LO_OFF);
207 writel(0, addr + WIN_REMAP_HI_OFF);
208 }
209}
210
211/* Checks whether the given window number is available */
212static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus,
213 const int win)
214{
215 void __iomem *addr = mbus->mbuswins_base +
216 mbus->soc->win_cfg_offset(win);
217 u32 ctrl = readl(addr + WIN_CTRL_OFF);
218 return !(ctrl & WIN_CTRL_ENABLE);
219}
220
221/*
222 * Checks whether the given (base, base+size) area doesn't overlap an
223 * existing region
224 */
225static int mvebu_mbus_window_conflicts(struct mvebu_mbus_state *mbus,
226 phys_addr_t base, size_t size,
227 u8 target, u8 attr)
228{
229 u64 end = (u64)base + size;
230 int win;
231
232 for (win = 0; win < mbus->soc->num_wins; win++) {
233 u64 wbase, wend;
234 u32 wsize;
235 u8 wtarget, wattr;
236 int enabled;
237
238 mvebu_mbus_read_window(mbus, win,
239 &enabled, &wbase, &wsize,
240 &wtarget, &wattr, NULL);
241
242 if (!enabled)
243 continue;
244
245 wend = wbase + wsize;
246
247 /*
248 * Check if the current window overlaps with the
249 * proposed physical range
250 */
251 if ((u64)base < wend && end > wbase)
252 return 0;
253
254 /*
255 * Check if target/attribute conflicts
256 */
257 if (target == wtarget && attr == wattr)
258 return 0;
259 }
260
261 return 1;
262}
263
264static int mvebu_mbus_find_window(struct mvebu_mbus_state *mbus,
265 phys_addr_t base, size_t size)
266{
267 int win;
268
269 for (win = 0; win < mbus->soc->num_wins; win++) {
270 u64 wbase;
271 u32 wsize;
272 int enabled;
273
274 mvebu_mbus_read_window(mbus, win,
275 &enabled, &wbase, &wsize,
276 NULL, NULL, NULL);
277
278 if (!enabled)
279 continue;
280
281 if (base == wbase && size == wsize)
282 return win;
283 }
284
285 return -ENODEV;
286}
287
288static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus,
289 int win, phys_addr_t base, size_t size,
290 phys_addr_t remap, u8 target,
291 u8 attr)
292{
293 void __iomem *addr = mbus->mbuswins_base +
294 mbus->soc->win_cfg_offset(win);
295 u32 ctrl, remap_addr;
296
297 ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) |
298 (attr << WIN_CTRL_ATTR_SHIFT) |
299 (target << WIN_CTRL_TGT_SHIFT) |
300 WIN_CTRL_ENABLE;
301
302 writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF);
303 writel(ctrl, addr + WIN_CTRL_OFF);
304 if (win < mbus->soc->num_remappable_wins) {
305 if (remap == MVEBU_MBUS_NO_REMAP)
306 remap_addr = base;
307 else
308 remap_addr = remap;
309 writel(remap_addr & WIN_REMAP_LOW, addr + WIN_REMAP_LO_OFF);
310 writel(0, addr + WIN_REMAP_HI_OFF);
311 }
312
313 return 0;
314}
315
316static int mvebu_mbus_alloc_window(struct mvebu_mbus_state *mbus,
317 phys_addr_t base, size_t size,
318 phys_addr_t remap, u8 target,
319 u8 attr)
320{
321 int win;
322
323 if (remap == MVEBU_MBUS_NO_REMAP) {
324 for (win = mbus->soc->num_remappable_wins;
325 win < mbus->soc->num_wins; win++)
326 if (mvebu_mbus_window_is_free(mbus, win))
327 return mvebu_mbus_setup_window(mbus, win, base,
328 size, remap,
329 target, attr);
330 }
331
332
333 for (win = 0; win < mbus->soc->num_wins; win++)
334 if (mvebu_mbus_window_is_free(mbus, win))
335 return mvebu_mbus_setup_window(mbus, win, base, size,
336 remap, target, attr);
337
338 return -ENOMEM;
339}
340
341/*
342 * Debugfs debugging
343 */
344
345/* Common function used for Dove, Kirkwood, Armada 370/XP and Orion 5x */
346static int mvebu_sdram_debug_show_orion(struct mvebu_mbus_state *mbus,
347 struct seq_file *seq, void *v)
348{
349 int i;
350
351 for (i = 0; i < 4; i++) {
352 u32 basereg = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
353 u32 sizereg = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
354 u64 base;
355 u32 size;
356
357 if (!(sizereg & DDR_SIZE_ENABLED)) {
358 seq_printf(seq, "[%d] disabled\n", i);
359 continue;
360 }
361
362 base = ((u64)basereg & DDR_BASE_CS_HIGH_MASK) << 32;
363 base |= basereg & DDR_BASE_CS_LOW_MASK;
364 size = (sizereg | ~DDR_SIZE_MASK);
365
366 seq_printf(seq, "[%d] %016llx - %016llx : cs%d\n",
367 i, (unsigned long long)base,
368 (unsigned long long)base + size + 1,
369 (sizereg & DDR_SIZE_CS_MASK) >> DDR_SIZE_CS_SHIFT);
370 }
371
372 return 0;
373}
374
375/* Special function for Dove */
376static int mvebu_sdram_debug_show_dove(struct mvebu_mbus_state *mbus,
377 struct seq_file *seq, void *v)
378{
379 int i;
380
381 for (i = 0; i < 2; i++) {
382 u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i));
383 u64 base;
384 u32 size;
385
386 if (!(map & 1)) {
387 seq_printf(seq, "[%d] disabled\n", i);
388 continue;
389 }
390
391 base = map & 0xff800000;
392 size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
393
394 seq_printf(seq, "[%d] %016llx - %016llx : cs%d\n",
395 i, (unsigned long long)base,
396 (unsigned long long)base + size, i);
397 }
398
399 return 0;
400}
401
402static int mvebu_sdram_debug_show(struct seq_file *seq, void *v)
403{
404 struct mvebu_mbus_state *mbus = &mbus_state;
405 return mbus->soc->show_cpu_target(mbus, seq, v);
406}
407
408static int mvebu_sdram_debug_open(struct inode *inode, struct file *file)
409{
410 return single_open(file, mvebu_sdram_debug_show, inode->i_private);
411}
412
413static const struct file_operations mvebu_sdram_debug_fops = {
414 .open = mvebu_sdram_debug_open,
415 .read = seq_read,
416 .llseek = seq_lseek,
417 .release = single_release,
418};
419
420static int mvebu_devs_debug_show(struct seq_file *seq, void *v)
421{
422 struct mvebu_mbus_state *mbus = &mbus_state;
423 int win;
424
425 for (win = 0; win < mbus->soc->num_wins; win++) {
426 u64 wbase, wremap;
427 u32 wsize;
428 u8 wtarget, wattr;
429 int enabled, i;
430 const char *name;
431
432 mvebu_mbus_read_window(mbus, win,
433 &enabled, &wbase, &wsize,
434 &wtarget, &wattr, &wremap);
435
436 if (!enabled) {
437 seq_printf(seq, "[%02d] disabled\n", win);
438 continue;
439 }
440
441
442 for (i = 0; mbus->soc->map[i].name; i++)
443 if (mbus->soc->map[i].target == wtarget &&
444 mbus->soc->map[i].attr ==
445 (wattr & mbus->soc->map[i].attrmask))
446 break;
447
448 name = mbus->soc->map[i].name ?: "unknown";
449
450 seq_printf(seq, "[%02d] %016llx - %016llx : %s",
451 win, (unsigned long long)wbase,
452 (unsigned long long)(wbase + wsize), name);
453
454 if (win < mbus->soc->num_remappable_wins) {
455 seq_printf(seq, " (remap %016llx)\n",
456 (unsigned long long)wremap);
457 } else
458 seq_printf(seq, "\n");
459 }
460
461 return 0;
462}
463
464static int mvebu_devs_debug_open(struct inode *inode, struct file *file)
465{
466 return single_open(file, mvebu_devs_debug_show, inode->i_private);
467}
468
469static const struct file_operations mvebu_devs_debug_fops = {
470 .open = mvebu_devs_debug_open,
471 .read = seq_read,
472 .llseek = seq_lseek,
473 .release = single_release,
474};
475
476/*
477 * SoC-specific functions and definitions
478 */
479
480static unsigned int orion_mbus_win_offset(int win)
481{
482 return win << 4;
483}
484
485static unsigned int armada_370_xp_mbus_win_offset(int win)
486{
487 /* The register layout is a bit annoying and the below code
488 * tries to cope with it.
489 * - At offset 0x0, there are the registers for the first 8
490 * windows, with 4 registers of 32 bits per window (ctrl,
491 * base, remap low, remap high)
492 * - Then at offset 0x80, there is a hole of 0x10 bytes for
493 * the internal registers base address and internal units
494 * sync barrier register.
495 * - Then at offset 0x90, there the registers for 12
496 * windows, with only 2 registers of 32 bits per window
497 * (ctrl, base).
498 */
499 if (win < 8)
500 return win << 4;
501 else
502 return 0x90 + ((win - 8) << 3);
503}
504
505static unsigned int mv78xx0_mbus_win_offset(int win)
506{
507 if (win < 8)
508 return win << 4;
509 else
510 return 0x900 + ((win - 8) << 4);
511}
512
513static void __init
514mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
515{
516 int i;
517 int cs;
518
519 mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
520
521 for (i = 0, cs = 0; i < 4; i++) {
522 u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
523 u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
524
525 /*
526 * We only take care of entries for which the chip
527 * select is enabled, and that don't have high base
528 * address bits set (devices can only access the first
529 * 32 bits of the memory).
530 */
531 if ((size & DDR_SIZE_ENABLED) &&
532 !(base & DDR_BASE_CS_HIGH_MASK)) {
533 struct mbus_dram_window *w;
534
535 w = &mvebu_mbus_dram_info.cs[cs++];
536 w->cs_index = i;
537 w->mbus_attr = 0xf & ~(1 << i);
538 if (mbus->hw_io_coherency)
539 w->mbus_attr |= ATTR_HW_COHERENCY;
540 w->base = base & DDR_BASE_CS_LOW_MASK;
541 w->size = (size | ~DDR_SIZE_MASK) + 1;
542 }
543 }
544 mvebu_mbus_dram_info.num_cs = cs;
545}
546
547static void __init
548mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus)
549{
550 int i;
551 int cs;
552
553 mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
554
555 for (i = 0, cs = 0; i < 2; i++) {
556 u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i));
557
558 /*
559 * Chip select enabled?
560 */
561 if (map & 1) {
562 struct mbus_dram_window *w;
563
564 w = &mvebu_mbus_dram_info.cs[cs++];
565 w->cs_index = i;
566 w->mbus_attr = 0; /* CS address decoding done inside */
567 /* the DDR controller, no need to */
568 /* provide attributes */
569 w->base = map & 0xff800000;
570 w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
571 }
572 }
573
574 mvebu_mbus_dram_info.num_cs = cs;
575}
576
577static const struct mvebu_mbus_mapping armada_370_map[] = {
578 MAPDEF("bootrom", 1, 0xe0, MAPDEF_NOMASK),
579 MAPDEF("devbus-boot", 1, 0x2f, MAPDEF_NOMASK),
580 MAPDEF("devbus-cs0", 1, 0x3e, MAPDEF_NOMASK),
581 MAPDEF("devbus-cs1", 1, 0x3d, MAPDEF_NOMASK),
582 MAPDEF("devbus-cs2", 1, 0x3b, MAPDEF_NOMASK),
583 MAPDEF("devbus-cs3", 1, 0x37, MAPDEF_NOMASK),
584 MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
585 MAPDEF("pcie1.0", 8, 0xe0, MAPDEF_PCIMASK),
586 {},
587};
588
589static const struct mvebu_mbus_soc_data armada_370_mbus_data = {
590 .num_wins = 20,
591 .num_remappable_wins = 8,
592 .win_cfg_offset = armada_370_xp_mbus_win_offset,
593 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
594 .show_cpu_target = mvebu_sdram_debug_show_orion,
595 .map = armada_370_map,
596};
597
598static const struct mvebu_mbus_mapping armada_xp_map[] = {
599 MAPDEF("bootrom", 1, 0x1d, MAPDEF_NOMASK),
600 MAPDEF("devbus-boot", 1, 0x2f, MAPDEF_NOMASK),
601 MAPDEF("devbus-cs0", 1, 0x3e, MAPDEF_NOMASK),
602 MAPDEF("devbus-cs1", 1, 0x3d, MAPDEF_NOMASK),
603 MAPDEF("devbus-cs2", 1, 0x3b, MAPDEF_NOMASK),
604 MAPDEF("devbus-cs3", 1, 0x37, MAPDEF_NOMASK),
605 MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
606 MAPDEF("pcie0.1", 4, 0xd0, MAPDEF_PCIMASK),
607 MAPDEF("pcie0.2", 4, 0xb0, MAPDEF_PCIMASK),
608 MAPDEF("pcie0.3", 4, 0x70, MAPDEF_PCIMASK),
609 MAPDEF("pcie1.0", 8, 0xe0, MAPDEF_PCIMASK),
610 MAPDEF("pcie1.1", 8, 0xd0, MAPDEF_PCIMASK),
611 MAPDEF("pcie1.2", 8, 0xb0, MAPDEF_PCIMASK),
612 MAPDEF("pcie1.3", 8, 0x70, MAPDEF_PCIMASK),
613 MAPDEF("pcie2.0", 4, 0xf0, MAPDEF_PCIMASK),
614 MAPDEF("pcie3.0", 8, 0xf0, MAPDEF_PCIMASK),
615 {},
616};
617
618static const struct mvebu_mbus_soc_data armada_xp_mbus_data = {
619 .num_wins = 20,
620 .num_remappable_wins = 8,
621 .win_cfg_offset = armada_370_xp_mbus_win_offset,
622 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
623 .show_cpu_target = mvebu_sdram_debug_show_orion,
624 .map = armada_xp_map,
625};
626
627static const struct mvebu_mbus_mapping kirkwood_map[] = {
628 MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
629 MAPDEF("pcie1.0", 4, 0xd0, MAPDEF_PCIMASK),
630 MAPDEF("sram", 3, 0x01, MAPDEF_NOMASK),
631 MAPDEF("nand", 1, 0x2f, MAPDEF_NOMASK),
632 {},
633};
634
635static const struct mvebu_mbus_soc_data kirkwood_mbus_data = {
636 .num_wins = 8,
637 .num_remappable_wins = 4,
638 .win_cfg_offset = orion_mbus_win_offset,
639 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
640 .show_cpu_target = mvebu_sdram_debug_show_orion,
641 .map = kirkwood_map,
642};
643
644static const struct mvebu_mbus_mapping dove_map[] = {
645 MAPDEF("pcie0.0", 0x4, 0xe0, MAPDEF_PCIMASK),
646 MAPDEF("pcie1.0", 0x8, 0xe0, MAPDEF_PCIMASK),
647 MAPDEF("cesa", 0x3, 0x01, MAPDEF_NOMASK),
648 MAPDEF("bootrom", 0x1, 0xfd, MAPDEF_NOMASK),
649 MAPDEF("scratchpad", 0xd, 0x0, MAPDEF_NOMASK),
650 {},
651};
652
653static const struct mvebu_mbus_soc_data dove_mbus_data = {
654 .num_wins = 8,
655 .num_remappable_wins = 4,
656 .win_cfg_offset = orion_mbus_win_offset,
657 .setup_cpu_target = mvebu_mbus_dove_setup_cpu_target,
658 .show_cpu_target = mvebu_sdram_debug_show_dove,
659 .map = dove_map,
660};
661
662static const struct mvebu_mbus_mapping orion5x_map[] = {
663 MAPDEF("pcie0.0", 4, 0x51, MAPDEF_ORIONPCIMASK),
664 MAPDEF("pci0.0", 3, 0x51, MAPDEF_ORIONPCIMASK),
665 MAPDEF("devbus-boot", 1, 0x0f, MAPDEF_NOMASK),
666 MAPDEF("devbus-cs0", 1, 0x1e, MAPDEF_NOMASK),
667 MAPDEF("devbus-cs1", 1, 0x1d, MAPDEF_NOMASK),
668 MAPDEF("devbus-cs2", 1, 0x1b, MAPDEF_NOMASK),
669 MAPDEF("sram", 0, 0x00, MAPDEF_NOMASK),
670 {},
671};
672
673/*
674 * Some variants of Orion5x have 4 remappable windows, some other have
675 * only two of them.
676 */
677static const struct mvebu_mbus_soc_data orion5x_4win_mbus_data = {
678 .num_wins = 8,
679 .num_remappable_wins = 4,
680 .win_cfg_offset = orion_mbus_win_offset,
681 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
682 .show_cpu_target = mvebu_sdram_debug_show_orion,
683 .map = orion5x_map,
684};
685
686static const struct mvebu_mbus_soc_data orion5x_2win_mbus_data = {
687 .num_wins = 8,
688 .num_remappable_wins = 2,
689 .win_cfg_offset = orion_mbus_win_offset,
690 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
691 .show_cpu_target = mvebu_sdram_debug_show_orion,
692 .map = orion5x_map,
693};
694
695static const struct mvebu_mbus_mapping mv78xx0_map[] = {
696 MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
697 MAPDEF("pcie0.1", 4, 0xd0, MAPDEF_PCIMASK),
698 MAPDEF("pcie0.2", 4, 0xb0, MAPDEF_PCIMASK),
699 MAPDEF("pcie0.3", 4, 0x70, MAPDEF_PCIMASK),
700 MAPDEF("pcie1.0", 8, 0xe0, MAPDEF_PCIMASK),
701 MAPDEF("pcie1.1", 8, 0xd0, MAPDEF_PCIMASK),
702 MAPDEF("pcie1.2", 8, 0xb0, MAPDEF_PCIMASK),
703 MAPDEF("pcie1.3", 8, 0x70, MAPDEF_PCIMASK),
704 MAPDEF("pcie2.0", 4, 0xf0, MAPDEF_PCIMASK),
705 MAPDEF("pcie3.0", 8, 0xf0, MAPDEF_PCIMASK),
706 {},
707};
708
709static const struct mvebu_mbus_soc_data mv78xx0_mbus_data = {
710 .num_wins = 14,
711 .num_remappable_wins = 8,
712 .win_cfg_offset = mv78xx0_mbus_win_offset,
713 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
714 .show_cpu_target = mvebu_sdram_debug_show_orion,
715 .map = mv78xx0_map,
716};
717
718/*
719 * The driver doesn't yet have a DT binding because the details of
720 * this DT binding still need to be sorted out. However, as a
721 * preparation, we already use of_device_id to match a SoC description
722 * string against the SoC specific details of this driver.
723 */
724static const struct of_device_id of_mvebu_mbus_ids[] = {
725 { .compatible = "marvell,armada370-mbus",
726 .data = &armada_370_mbus_data, },
727 { .compatible = "marvell,armadaxp-mbus",
728 .data = &armada_xp_mbus_data, },
729 { .compatible = "marvell,kirkwood-mbus",
730 .data = &kirkwood_mbus_data, },
731 { .compatible = "marvell,dove-mbus",
732 .data = &dove_mbus_data, },
733 { .compatible = "marvell,orion5x-88f5281-mbus",
734 .data = &orion5x_4win_mbus_data, },
735 { .compatible = "marvell,orion5x-88f5182-mbus",
736 .data = &orion5x_2win_mbus_data, },
737 { .compatible = "marvell,orion5x-88f5181-mbus",
738 .data = &orion5x_2win_mbus_data, },
739 { .compatible = "marvell,orion5x-88f6183-mbus",
740 .data = &orion5x_4win_mbus_data, },
741 { .compatible = "marvell,mv78xx0-mbus",
742 .data = &mv78xx0_mbus_data, },
743 { },
744};
745
746/*
747 * Public API of the driver
748 */
749int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
750 size_t size, phys_addr_t remap,
751 unsigned int flags)
752{
753 struct mvebu_mbus_state *s = &mbus_state;
754 u8 target, attr;
755 int i;
756
757 if (!s->soc->map)
758 return -ENODEV;
759
760 for (i = 0; s->soc->map[i].name; i++)
761 if (!strcmp(s->soc->map[i].name, devname))
762 break;
763
764 if (!s->soc->map[i].name) {
765 pr_err("mvebu-mbus: unknown device '%s'\n", devname);
766 return -ENODEV;
767 }
768
769 target = s->soc->map[i].target;
770 attr = s->soc->map[i].attr;
771
772 if (flags == MVEBU_MBUS_PCI_MEM)
773 attr |= 0x8;
774 else if (flags == MVEBU_MBUS_PCI_WA)
775 attr |= 0x28;
776
777 if (!mvebu_mbus_window_conflicts(s, base, size, target, attr)) {
778 pr_err("mvebu-mbus: cannot add window '%s', conflicts with another window\n",
779 devname);
780 return -EINVAL;
781 }
782
783 return mvebu_mbus_alloc_window(s, base, size, remap, target, attr);
784
785}
786
787int mvebu_mbus_add_window(const char *devname, phys_addr_t base, size_t size)
788{
789 return mvebu_mbus_add_window_remap_flags(devname, base, size,
790 MVEBU_MBUS_NO_REMAP, 0);
791}
792
793int mvebu_mbus_del_window(phys_addr_t base, size_t size)
794{
795 int win;
796
797 win = mvebu_mbus_find_window(&mbus_state, base, size);
798 if (win < 0)
799 return win;
800
801 mvebu_mbus_disable_window(&mbus_state, win);
802 return 0;
803}
804
805static __init int mvebu_mbus_debugfs_init(void)
806{
807 struct mvebu_mbus_state *s = &mbus_state;
808
809 /*
810 * If no base has been initialized, doesn't make sense to
811 * register the debugfs entries. We may be on a multiplatform
812 * kernel that isn't running a Marvell EBU SoC.
813 */
814 if (!s->mbuswins_base)
815 return 0;
816
817 s->debugfs_root = debugfs_create_dir("mvebu-mbus", NULL);
818 if (s->debugfs_root) {
819 s->debugfs_sdram = debugfs_create_file("sdram", S_IRUGO,
820 s->debugfs_root, NULL,
821 &mvebu_sdram_debug_fops);
822 s->debugfs_devs = debugfs_create_file("devices", S_IRUGO,
823 s->debugfs_root, NULL,
824 &mvebu_devs_debug_fops);
825 }
826
827 return 0;
828}
829fs_initcall(mvebu_mbus_debugfs_init);
830
831int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base,
832 size_t mbuswins_size,
833 phys_addr_t sdramwins_phys_base,
834 size_t sdramwins_size)
835{
836 struct mvebu_mbus_state *mbus = &mbus_state;
837 const struct of_device_id *of_id;
838 int win;
839
840 for (of_id = of_mvebu_mbus_ids; of_id->compatible; of_id++)
841 if (!strcmp(of_id->compatible, soc))
842 break;
843
844 if (!of_id->compatible) {
845 pr_err("mvebu-mbus: could not find a matching SoC family\n");
846 return -ENODEV;
847 }
848
849 mbus->soc = of_id->data;
850
851 mbus->mbuswins_base = ioremap(mbuswins_phys_base, mbuswins_size);
852 if (!mbus->mbuswins_base)
853 return -ENOMEM;
854
855 mbus->sdramwins_base = ioremap(sdramwins_phys_base, sdramwins_size);
856 if (!mbus->sdramwins_base) {
857 iounmap(mbus_state.mbuswins_base);
858 return -ENOMEM;
859 }
860
861 if (of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric"))
862 mbus->hw_io_coherency = 1;
863
864 for (win = 0; win < mbus->soc->num_wins; win++)
865 mvebu_mbus_disable_window(mbus, win);
866
867 mbus->soc->setup_cpu_target(mbus);
868
869 return 0;
870}
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c
index 62dcdcdec940..791a6719d8a9 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c
@@ -2552,7 +2552,7 @@ static const char * const intc_groups[] = {
2552 "intc_irq2", 2552 "intc_irq2",
2553 "intc_irq2_b", 2553 "intc_irq2_b",
2554 "intc_irq3", 2554 "intc_irq3",
2555 "intc_irq4_b", 2555 "intc_irq3_b",
2556}; 2556};
2557 2557
2558static const char * const lbsc_groups[] = { 2558static const char * const lbsc_groups[] = {
diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c
index 0880ef1a01ba..0127601c26c7 100644
--- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c
+++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c
@@ -16,6 +16,7 @@
16#include <linux/export.h> 16#include <linux/export.h>
17#include <linux/types.h> 17#include <linux/types.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/reset.h>
19#include <linux/platform_device.h> 20#include <linux/platform_device.h>
20#include <linux/err.h> 21#include <linux/err.h>
21#include <linux/spinlock.h> 22#include <linux/spinlock.h>
@@ -661,7 +662,7 @@ int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
661} 662}
662EXPORT_SYMBOL_GPL(ipu_idmac_disable_channel); 663EXPORT_SYMBOL_GPL(ipu_idmac_disable_channel);
663 664
664static int ipu_reset(struct ipu_soc *ipu) 665static int ipu_memory_reset(struct ipu_soc *ipu)
665{ 666{
666 unsigned long timeout; 667 unsigned long timeout;
667 668
@@ -1105,7 +1106,12 @@ static int ipu_probe(struct platform_device *pdev)
1105 if (ret) 1106 if (ret)
1106 goto out_failed_irq; 1107 goto out_failed_irq;
1107 1108
1108 ret = ipu_reset(ipu); 1109 ret = device_reset(&pdev->dev);
1110 if (ret) {
1111 dev_err(&pdev->dev, "failed to reset: %d\n", ret);
1112 goto out_failed_reset;
1113 }
1114 ret = ipu_memory_reset(ipu);
1109 if (ret) 1115 if (ret)
1110 goto out_failed_reset; 1116 goto out_failed_reset;
1111 1117
@@ -1131,8 +1137,8 @@ static int ipu_probe(struct platform_device *pdev)
1131failed_add_clients: 1137failed_add_clients:
1132 ipu_submodules_exit(ipu); 1138 ipu_submodules_exit(ipu);
1133failed_submodules_init: 1139failed_submodules_init:
1134 ipu_irq_exit(ipu);
1135out_failed_reset: 1140out_failed_reset:
1141 ipu_irq_exit(ipu);
1136out_failed_irq: 1142out_failed_irq:
1137 clk_disable_unprepare(ipu->clk); 1143 clk_disable_unprepare(ipu->clk);
1138failed_clk_get: 1144failed_clk_get:
diff --git a/include/linux/mbus.h b/include/linux/mbus.h
index efa1a6d7aca8..dba482e31a13 100644
--- a/include/linux/mbus.h
+++ b/include/linux/mbus.h
@@ -32,6 +32,20 @@ struct mbus_dram_target_info
32 } cs[4]; 32 } cs[4];
33}; 33};
34 34
35/* Flags for PCI/PCIe address decoding regions */
36#define MVEBU_MBUS_PCI_IO 0x1
37#define MVEBU_MBUS_PCI_MEM 0x2
38#define MVEBU_MBUS_PCI_WA 0x3
39
40/*
41 * Magic value that explicits that we don't need a remapping-capable
42 * address decoding window.
43 */
44#define MVEBU_MBUS_NO_REMAP (0xffffffff)
45
46/* Maximum size of a mbus window name */
47#define MVEBU_MBUS_MAX_WINNAME_SZ 32
48
35/* 49/*
36 * The Marvell mbus is to be found only on SOCs from the Orion family 50 * The Marvell mbus is to be found only on SOCs from the Orion family
37 * at the moment. Provide a dummy stub for other architectures. 51 * at the moment. Provide a dummy stub for other architectures.
@@ -44,4 +58,15 @@ static inline const struct mbus_dram_target_info *mv_mbus_dram_info(void)
44 return NULL; 58 return NULL;
45} 59}
46#endif 60#endif
47#endif 61
62int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
63 size_t size, phys_addr_t remap,
64 unsigned int flags);
65int mvebu_mbus_add_window(const char *devname, phys_addr_t base,
66 size_t size);
67int mvebu_mbus_del_window(phys_addr_t base, size_t size);
68int mvebu_mbus_init(const char *soc, phys_addr_t mbus_phys_base,
69 size_t mbus_size, phys_addr_t sdram_phys_base,
70 size_t sdram_size);
71
72#endif /* __LINUX_MBUS_H */