aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-11-02 00:08:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-11-02 00:08:03 -0400
commit994c0e992522c123298b4a91b72f5e67ba2d1123 (patch)
tree411952f844b8e1d5ef2854e44df793529078d3eb /arch
parent367069f16e32e188d4687fe2c3e30f2ca583836f (diff)
parentabc3f126ac736280c68db6472eb0040ddf6e1b1f (diff)
Merge branch 'next/soc' of git://git.linaro.org/people/arnd/arm-soc
* 'next/soc' of git://git.linaro.org/people/arnd/arm-soc: (21 commits) MAINTAINERS: add ARM/FREESCALE IMX6 entry arm/imx: merge i.MX3 and i.MX6 arm/imx6q: add suspend/resume support arm/imx6q: add device tree machine support arm/imx6q: add smp and cpu hotplug support arm/imx6q: add core drivers clock, gpc, mmdc and src arm/imx: add gic_handle_irq function arm/imx6q: add core definitions and low-level debug uart arm/imx6q: add device tree source ARM: highbank: add suspend support ARM: highbank: Add cpu hotplug support ARM: highbank: add SMP support MAINTAINERS: add Calxeda Highbank ARM platform ARM: add Highbank core platform support ARM: highbank: add devicetree source ARM: l2x0: add empty l2x0_of_init picoxcell: add a definition of VMALLOC_END picoxcell: remove custom ioremap implementation picoxcell: add the DTS for the PC7302 board picoxcell: add the DTS for pc3x2 and pc3x3 devices ... Fix up trivial conflicts in arch/arm/Kconfig, and some more header file conflicts in arch/arm/mach-omap2/board-generic.c (as per an ealier merge by Arnd).
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig34
-rw-r--r--arch/arm/Kconfig.debug14
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/boot/dts/highbank.dts198
-rw-r--r--arch/arm/boot/dts/imx6q-sabreauto.dts62
-rw-r--r--arch/arm/boot/dts/imx6q.dtsi575
-rw-r--r--arch/arm/boot/dts/picoxcell-pc3x2.dtsi249
-rw-r--r--arch/arm/boot/dts/picoxcell-pc3x3.dtsi365
-rw-r--r--arch/arm/boot/dts/picoxcell-pc7302-pc3x2.dts86
-rw-r--r--arch/arm/boot/dts/picoxcell-pc7302-pc3x3.dts92
-rw-r--r--arch/arm/include/asm/hardware/cache-l2x0.h9
-rw-r--r--arch/arm/mach-highbank/Makefile6
-rw-r--r--arch/arm/mach-highbank/Makefile.boot1
-rw-r--r--arch/arm/mach-highbank/clock.c62
-rw-r--r--arch/arm/mach-highbank/core.h9
-rw-r--r--arch/arm/mach-highbank/highbank.c145
-rw-r--r--arch/arm/mach-highbank/hotplug.c56
-rw-r--r--arch/arm/mach-highbank/include/mach/debug-macro.S19
-rw-r--r--arch/arm/mach-highbank/include/mach/entry-macro.S7
-rw-r--r--arch/arm/mach-highbank/include/mach/gpio.h1
-rw-r--r--arch/arm/mach-highbank/include/mach/io.h7
-rw-r--r--arch/arm/mach-highbank/include/mach/irqs.h6
-rw-r--r--arch/arm/mach-highbank/include/mach/memory.h1
-rw-r--r--arch/arm/mach-highbank/include/mach/system.h26
-rw-r--r--arch/arm/mach-highbank/include/mach/timex.h6
-rw-r--r--arch/arm/mach-highbank/include/mach/uncompress.h9
-rw-r--r--arch/arm/mach-highbank/include/mach/vmalloc.h1
-rw-r--r--arch/arm/mach-highbank/lluart.c34
-rw-r--r--arch/arm/mach-highbank/localtimer.c40
-rw-r--r--arch/arm/mach-highbank/platsmp.c78
-rw-r--r--arch/arm/mach-highbank/pm.c55
-rw-r--r--arch/arm/mach-highbank/sysregs.h52
-rw-r--r--arch/arm/mach-highbank/system.c33
-rw-r--r--arch/arm/mach-imx/Kconfig30
-rw-r--r--arch/arm/mach-imx/Makefile11
-rw-r--r--arch/arm/mach-imx/Makefile.boot4
-rw-r--r--arch/arm/mach-imx/clock-imx6q.c2012
-rw-r--r--arch/arm/mach-imx/gpc.c113
-rw-r--r--arch/arm/mach-imx/head-v7.S99
-rw-r--r--arch/arm/mach-imx/hotplug.c44
-rw-r--r--arch/arm/mach-imx/lluart.c32
-rw-r--r--arch/arm/mach-imx/localtimer.c35
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c84
-rw-r--r--arch/arm/mach-imx/mmdc.c72
-rw-r--r--arch/arm/mach-imx/platsmp.c85
-rw-r--r--arch/arm/mach-imx/pm-imx6q.c70
-rw-r--r--arch/arm/mach-imx/src.c49
-rw-r--r--arch/arm/mach-omap2/board-generic.c1
-rw-r--r--arch/arm/mach-picoxcell/Makefile3
-rw-r--r--arch/arm/mach-picoxcell/Makefile.boot1
-rw-r--r--arch/arm/mach-picoxcell/common.c55
-rw-r--r--arch/arm/mach-picoxcell/common.h18
-rw-r--r--arch/arm/mach-picoxcell/include/mach/debug-macro.S35
-rw-r--r--arch/arm/mach-picoxcell/include/mach/entry-macro.S19
-rw-r--r--arch/arm/mach-picoxcell/include/mach/gpio.h1
-rw-r--r--arch/arm/mach-picoxcell/include/mach/hardware.h21
-rw-r--r--arch/arm/mach-picoxcell/include/mach/io.h22
-rw-r--r--arch/arm/mach-picoxcell/include/mach/irqs.h25
-rw-r--r--arch/arm/mach-picoxcell/include/mach/map.h25
-rw-r--r--arch/arm/mach-picoxcell/include/mach/memory.h1
-rw-r--r--arch/arm/mach-picoxcell/include/mach/picoxcell_soc.h25
-rw-r--r--arch/arm/mach-picoxcell/include/mach/system.h31
-rw-r--r--arch/arm/mach-picoxcell/include/mach/timex.h25
-rw-r--r--arch/arm/mach-picoxcell/include/mach/uncompress.h21
-rw-r--r--arch/arm/mach-picoxcell/include/mach/vmalloc.h14
-rw-r--r--arch/arm/mach-picoxcell/io.c32
-rw-r--r--arch/arm/mach-picoxcell/time.c132
-rw-r--r--arch/arm/mm/Kconfig4
-rw-r--r--arch/arm/plat-mxc/Kconfig11
-rw-r--r--arch/arm/plat-mxc/Makefile2
-rw-r--r--arch/arm/plat-mxc/gic.c48
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h29
-rw-r--r--arch/arm/plat-mxc/include/mach/debug-macro.S2
-rw-r--r--arch/arm/plat-mxc/include/mach/entry-macro.S6
-rw-r--r--arch/arm/plat-mxc/include/mach/hardware.h6
-rw-r--r--arch/arm/plat-mxc/include/mach/irqs.h10
-rw-r--r--arch/arm/plat-mxc/include/mach/mx6q.h33
77 files changed, 5726 insertions, 14 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bcc067006342..fe6b0526b3a6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -334,6 +334,20 @@ config ARCH_BCMRING
334 help 334 help
335 Support for Broadcom's BCMRing platform. 335 Support for Broadcom's BCMRing platform.
336 336
337config ARCH_HIGHBANK
338 bool "Calxeda Highbank-based"
339 select ARCH_WANT_OPTIONAL_GPIOLIB
340 select ARM_AMBA
341 select ARM_GIC
342 select ARM_TIMER_SP804
343 select CLKDEV_LOOKUP
344 select CPU_V7
345 select GENERIC_CLOCKEVENTS
346 select HAVE_ARM_SCU
347 select USE_OF
348 help
349 Support for the Calxeda Highbank SoC based boards.
350
337config ARCH_CLPS711X 351config ARCH_CLPS711X
338 bool "Cirrus Logic CLPS711x/EP721x-based" 352 bool "Cirrus Logic CLPS711x/EP721x-based"
339 select CPU_ARM720T 353 select CPU_ARM720T
@@ -623,6 +637,24 @@ config ARCH_TEGRA
623 This enables support for NVIDIA Tegra based systems (Tegra APX, 637 This enables support for NVIDIA Tegra based systems (Tegra APX,
624 Tegra 6xx and Tegra 2 series). 638 Tegra 6xx and Tegra 2 series).
625 639
640config ARCH_PICOXCELL
641 bool "Picochip picoXcell"
642 select ARCH_REQUIRE_GPIOLIB
643 select ARM_PATCH_PHYS_VIRT
644 select ARM_VIC
645 select CPU_V6K
646 select DW_APB_TIMER
647 select GENERIC_CLOCKEVENTS
648 select GENERIC_GPIO
649 select HAVE_SCHED_CLOCK
650 select HAVE_TCM
651 select NO_IOPORT
652 select USE_OF
653 help
654 This enables support for systems based on the Picochip picoXcell
655 family of Femtocell devices. The picoxcell support requires device tree
656 for all boards.
657
626config ARCH_PNX4008 658config ARCH_PNX4008
627 bool "Philips Nexperia PNX4008 Mobile" 659 bool "Philips Nexperia PNX4008 Mobile"
628 select CPU_ARM926T 660 select CPU_ARM926T
@@ -1398,7 +1430,7 @@ config SMP
1398 depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \ 1430 depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
1399 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \ 1431 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
1400 ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \ 1432 ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
1401 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE 1433 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || ARCH_HIGHBANK || SOC_IMX6Q
1402 depends on MMU 1434 depends on MMU
1403 select USE_GENERIC_SMP_HELPERS 1435 select USE_GENERIC_SMP_HELPERS
1404 select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP 1436 select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 64db5b1648e5..c5213e78606b 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -128,6 +128,13 @@ choice
128 Say Y here if you want the debug print routines to direct 128 Say Y here if you want the debug print routines to direct
129 their output to the second serial port on these devices. 129 their output to the second serial port on these devices.
130 130
131 config DEBUG_HIGHBANK_UART
132 bool "Kernel low-level debugging messages via Highbank UART"
133 depends on ARCH_HIGHBANK
134 help
135 Say Y here if you want the debug print routines to direct
136 their output to the UART on Highbank based devices.
137
131 config DEBUG_IMX1_UART 138 config DEBUG_IMX1_UART
132 bool "i.MX1 Debug UART" 139 bool "i.MX1 Debug UART"
133 depends on SOC_IMX1 140 depends on SOC_IMX1
@@ -184,6 +191,13 @@ choice
184 Say Y here if you want kernel low-level debugging support 191 Say Y here if you want kernel low-level debugging support
185 on i.MX50 or i.MX53. 192 on i.MX50 or i.MX53.
186 193
194 config DEBUG_IMX6Q_UART
195 bool "i.MX6Q Debug UART"
196 depends on SOC_IMX6Q
197 help
198 Say Y here if you want kernel low-level debugging support
199 on i.MX6Q.
200
187 config DEBUG_S3C_UART0 201 config DEBUG_S3C_UART0
188 depends on PLAT_SAMSUNG 202 depends on PLAT_SAMSUNG
189 bool "Use S3C UART 0 for low-level debug" 203 bool "Use S3C UART 0 for low-level debug"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 30b920148202..b7c2d377a6c2 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -144,6 +144,7 @@ machine-$(CONFIG_ARCH_EBSA110) := ebsa110
144machine-$(CONFIG_ARCH_EP93XX) := ep93xx 144machine-$(CONFIG_ARCH_EP93XX) := ep93xx
145machine-$(CONFIG_ARCH_GEMINI) := gemini 145machine-$(CONFIG_ARCH_GEMINI) := gemini
146machine-$(CONFIG_ARCH_H720X) := h720x 146machine-$(CONFIG_ARCH_H720X) := h720x
147machine-$(CONFIG_ARCH_HIGHBANK) := highbank
147machine-$(CONFIG_ARCH_INTEGRATOR) := integrator 148machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
148machine-$(CONFIG_ARCH_IOP13XX) := iop13xx 149machine-$(CONFIG_ARCH_IOP13XX) := iop13xx
149machine-$(CONFIG_ARCH_IOP32X) := iop32x 150machine-$(CONFIG_ARCH_IOP32X) := iop32x
@@ -158,7 +159,7 @@ machine-$(CONFIG_ARCH_MMP) := mmp
158machine-$(CONFIG_ARCH_MSM) := msm 159machine-$(CONFIG_ARCH_MSM) := msm
159machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0 160machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
160machine-$(CONFIG_ARCH_IMX_V4_V5) := imx 161machine-$(CONFIG_ARCH_IMX_V4_V5) := imx
161machine-$(CONFIG_ARCH_MX3) := imx 162machine-$(CONFIG_ARCH_IMX_V6_V7) := imx
162machine-$(CONFIG_ARCH_MX5) := mx5 163machine-$(CONFIG_ARCH_MX5) := mx5
163machine-$(CONFIG_ARCH_MXS) := mxs 164machine-$(CONFIG_ARCH_MXS) := mxs
164machine-$(CONFIG_ARCH_NETX) := netx 165machine-$(CONFIG_ARCH_NETX) := netx
@@ -168,6 +169,7 @@ machine-$(CONFIG_ARCH_OMAP2) := omap2
168machine-$(CONFIG_ARCH_OMAP3) := omap2 169machine-$(CONFIG_ARCH_OMAP3) := omap2
169machine-$(CONFIG_ARCH_OMAP4) := omap2 170machine-$(CONFIG_ARCH_OMAP4) := omap2
170machine-$(CONFIG_ARCH_ORION5X) := orion5x 171machine-$(CONFIG_ARCH_ORION5X) := orion5x
172machine-$(CONFIG_ARCH_PICOXCELL) := picoxcell
171machine-$(CONFIG_ARCH_PNX4008) := pnx4008 173machine-$(CONFIG_ARCH_PNX4008) := pnx4008
172machine-$(CONFIG_ARCH_PRIMA2) := prima2 174machine-$(CONFIG_ARCH_PRIMA2) := prima2
173machine-$(CONFIG_ARCH_PXA) := pxa 175machine-$(CONFIG_ARCH_PXA) := pxa
diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
new file mode 100644
index 000000000000..aeb1a7578fad
--- /dev/null
+++ b/arch/arm/boot/dts/highbank.dts
@@ -0,0 +1,198 @@
1/*
2 * Copyright 2011 Calxeda, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17/dts-v1/;
18
19/* First 4KB has pen for secondary cores. */
20/memreserve/ 0x00000000 0x0001000;
21
22/ {
23 model = "Calxeda Highbank";
24 compatible = "calxeda,highbank";
25 #address-cells = <1>;
26 #size-cells = <1>;
27
28 cpus {
29 #address-cells = <1>;
30 #size-cells = <0>;
31
32 cpu@0 {
33 compatible = "arm,cortex-a9";
34 reg = <0>;
35 next-level-cache = <&L2>;
36 };
37
38 cpu@1 {
39 compatible = "arm,cortex-a9";
40 reg = <1>;
41 next-level-cache = <&L2>;
42 };
43
44 cpu@2 {
45 compatible = "arm,cortex-a9";
46 reg = <2>;
47 next-level-cache = <&L2>;
48 };
49
50 cpu@3 {
51 compatible = "arm,cortex-a9";
52 reg = <3>;
53 next-level-cache = <&L2>;
54 };
55 };
56
57 memory {
58 name = "memory";
59 device_type = "memory";
60 reg = <0x00000000 0xff900000>;
61 };
62
63 chosen {
64 bootargs = "console=ttyAMA0";
65 };
66
67 soc {
68 #address-cells = <1>;
69 #size-cells = <1>;
70 compatible = "simple-bus";
71 interrupt-parent = <&intc>;
72 ranges;
73
74 timer@fff10600 {
75 compatible = "arm,smp-twd";
76 reg = <0xfff10600 0x20>;
77 interrupts = <1 13 0xf04>;
78 };
79
80 watchdog@fff10620 {
81 compatible = "arm,cortex-a9-wdt";
82 reg = <0xfff10620 0x20>;
83 interrupts = <1 14 0xf04>;
84 };
85
86 intc: interrupt-controller@fff11000 {
87 compatible = "arm,cortex-a9-gic";
88 #interrupt-cells = <3>;
89 #size-cells = <0>;
90 #address-cells = <1>;
91 interrupt-controller;
92 interrupt-parent;
93 reg = <0xfff11000 0x1000>,
94 <0xfff10100 0x100>;
95 };
96
97 L2: l2-cache {
98 compatible = "arm,pl310-cache";
99 reg = <0xfff12000 0x1000>;
100 interrupts = <0 70 4>;
101 cache-unified;
102 cache-level = <2>;
103 };
104
105 pmu {
106 compatible = "arm,cortex-a9-pmu";
107 interrupts = <0 76 4 0 75 4 0 74 4 0 73 4>;
108 };
109
110 sata@ffe08000 {
111 compatible = "calxeda,hb-ahci";
112 reg = <0xffe08000 0x10000>;
113 interrupts = <0 83 4>;
114 };
115
116 sdhci@ffe0e000 {
117 compatible = "calxeda,hb-sdhci";
118 reg = <0xffe0e000 0x1000>;
119 interrupts = <0 90 4>;
120 };
121
122 ipc@fff20000 {
123 compatible = "arm,pl320", "arm,primecell";
124 reg = <0xfff20000 0x1000>;
125 interrupts = <0 7 4>;
126 };
127
128 gpioe: gpio@fff30000 {
129 #gpio-cells = <2>;
130 compatible = "arm,pl061", "arm,primecell";
131 gpio-controller;
132 reg = <0xfff30000 0x1000>;
133 interrupts = <0 14 4>;
134 };
135
136 gpiof: gpio@fff31000 {
137 #gpio-cells = <2>;
138 compatible = "arm,pl061", "arm,primecell";
139 gpio-controller;
140 reg = <0xfff31000 0x1000>;
141 interrupts = <0 15 4>;
142 };
143
144 gpiog: gpio@fff32000 {
145 #gpio-cells = <2>;
146 compatible = "arm,pl061", "arm,primecell";
147 gpio-controller;
148 reg = <0xfff32000 0x1000>;
149 interrupts = <0 16 4>;
150 };
151
152 gpioh: gpio@fff33000 {
153 #gpio-cells = <2>;
154 compatible = "arm,pl061", "arm,primecell";
155 gpio-controller;
156 reg = <0xfff33000 0x1000>;
157 interrupts = <0 17 4>;
158 };
159
160 timer {
161 compatible = "arm,sp804", "arm,primecell";
162 reg = <0xfff34000 0x1000>;
163 interrupts = <0 18 4>;
164 };
165
166 rtc@fff35000 {
167 compatible = "arm,pl031", "arm,primecell";
168 reg = <0xfff35000 0x1000>;
169 interrupts = <0 19 4>;
170 };
171
172 serial@fff36000 {
173 compatible = "arm,pl011", "arm,primecell";
174 reg = <0xfff36000 0x1000>;
175 interrupts = <0 20 4>;
176 };
177
178 smic@fff3a000 {
179 compatible = "ipmi-smic";
180 device_type = "ipmi";
181 reg = <0xfff3a000 0x1000>;
182 interrupts = <0 24 4>;
183 reg-size = <4>;
184 reg-spacing = <4>;
185 };
186
187 sregs@fff3c000 {
188 compatible = "calxeda,hb-sregs";
189 reg = <0xfff3c000 0x1000>;
190 };
191
192 dma@fff3d000 {
193 compatible = "arm,pl330", "arm,primecell";
194 reg = <0xfff3d000 0x1000>;
195 interrupts = <0 92 4>;
196 };
197 };
198};
diff --git a/arch/arm/boot/dts/imx6q-sabreauto.dts b/arch/arm/boot/dts/imx6q-sabreauto.dts
new file mode 100644
index 000000000000..072974e443f2
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabreauto.dts
@@ -0,0 +1,62 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13/dts-v1/;
14/include/ "imx6q.dtsi"
15
16/ {
17 model = "Freescale i.MX6 Quad SABRE Automotive Board";
18 compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
19
20 chosen {
21 bootargs = "console=ttymxc0,115200 root=/dev/mmcblk3p3 rootwait";
22 };
23
24 memory {
25 reg = <0x10000000 0x80000000>;
26 };
27
28 soc {
29 aips-bus@02100000 { /* AIPS2 */
30 enet@02188000 {
31 phy-mode = "rgmii";
32 local-mac-address = [00 04 9F 01 1B 61];
33 status = "okay";
34 };
35
36 usdhc@02198000 { /* uSDHC3 */
37 cd-gpios = <&gpio5 11 0>; /* GPIO6_11 */
38 wp-gpios = <&gpio5 14 0>; /* GPIO6_14 */
39 status = "okay";
40 };
41
42 usdhc@0219c000 { /* uSDHC4 */
43 fsl,card-wired;
44 status = "okay";
45 };
46
47 uart3: uart@021f0000 { /* UART4 */
48 status = "okay";
49 };
50 };
51 };
52
53 leds {
54 compatible = "gpio-leds";
55
56 debug-led {
57 label = "Heartbeat";
58 gpios = <&gpio2 25 0>; /* GPIO3_25 */
59 linux,default-trigger = "heartbeat";
60 };
61 };
62};
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
new file mode 100644
index 000000000000..7dda599558cc
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -0,0 +1,575 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13/include/ "skeleton.dtsi"
14
15/ {
16 aliases {
17 serial0 = &uart0;
18 serial1 = &uart1;
19 serial2 = &uart2;
20 serial3 = &uart3;
21 serial4 = &uart4;
22 };
23
24 cpus {
25 #address-cells = <1>;
26 #size-cells = <0>;
27
28 cpu@0 {
29 compatible = "arm,cortex-a9";
30 reg = <0>;
31 next-level-cache = <&L2>;
32 };
33
34 cpu@1 {
35 compatible = "arm,cortex-a9";
36 reg = <1>;
37 next-level-cache = <&L2>;
38 };
39
40 cpu@2 {
41 compatible = "arm,cortex-a9";
42 reg = <2>;
43 next-level-cache = <&L2>;
44 };
45
46 cpu@3 {
47 compatible = "arm,cortex-a9";
48 reg = <3>;
49 next-level-cache = <&L2>;
50 };
51 };
52
53 intc: interrupt-controller@00a01000 {
54 compatible = "arm,cortex-a9-gic";
55 #interrupt-cells = <3>;
56 #address-cells = <1>;
57 #size-cells = <1>;
58 interrupt-controller;
59 reg = <0x00a01000 0x1000>,
60 <0x00a00100 0x100>;
61 };
62
63 clocks {
64 #address-cells = <1>;
65 #size-cells = <0>;
66
67 ckil {
68 compatible = "fsl,imx-ckil", "fixed-clock";
69 clock-frequency = <32768>;
70 };
71
72 ckih1 {
73 compatible = "fsl,imx-ckih1", "fixed-clock";
74 clock-frequency = <0>;
75 };
76
77 osc {
78 compatible = "fsl,imx-osc", "fixed-clock";
79 clock-frequency = <24000000>;
80 };
81 };
82
83 soc {
84 #address-cells = <1>;
85 #size-cells = <1>;
86 compatible = "simple-bus";
87 interrupt-parent = <&intc>;
88 ranges;
89
90 timer@00a00600 {
91 compatible = "arm,smp-twd";
92 reg = <0x00a00600 0x100>;
93 interrupts = <1 13 0xf4>;
94 };
95
96 L2: l2-cache@00a02000 {
97 compatible = "arm,pl310-cache";
98 reg = <0x00a02000 0x1000>;
99 interrupts = <0 92 0x04>;
100 cache-unified;
101 cache-level = <2>;
102 };
103
104 aips-bus@02000000 { /* AIPS1 */
105 compatible = "fsl,aips-bus", "simple-bus";
106 #address-cells = <1>;
107 #size-cells = <1>;
108 reg = <0x02000000 0x100000>;
109 ranges;
110
111 spba-bus@02000000 {
112 compatible = "fsl,spba-bus", "simple-bus";
113 #address-cells = <1>;
114 #size-cells = <1>;
115 reg = <0x02000000 0x40000>;
116 ranges;
117
118 spdif@02004000 {
119 reg = <0x02004000 0x4000>;
120 interrupts = <0 52 0x04>;
121 };
122
123 ecspi@02008000 { /* eCSPI1 */
124 #address-cells = <1>;
125 #size-cells = <0>;
126 compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
127 reg = <0x02008000 0x4000>;
128 interrupts = <0 31 0x04>;
129 status = "disabled";
130 };
131
132 ecspi@0200c000 { /* eCSPI2 */
133 #address-cells = <1>;
134 #size-cells = <0>;
135 compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
136 reg = <0x0200c000 0x4000>;
137 interrupts = <0 32 0x04>;
138 status = "disabled";
139 };
140
141 ecspi@02010000 { /* eCSPI3 */
142 #address-cells = <1>;
143 #size-cells = <0>;
144 compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
145 reg = <0x02010000 0x4000>;
146 interrupts = <0 33 0x04>;
147 status = "disabled";
148 };
149
150 ecspi@02014000 { /* eCSPI4 */
151 #address-cells = <1>;
152 #size-cells = <0>;
153 compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
154 reg = <0x02014000 0x4000>;
155 interrupts = <0 34 0x04>;
156 status = "disabled";
157 };
158
159 ecspi@02018000 { /* eCSPI5 */
160 #address-cells = <1>;
161 #size-cells = <0>;
162 compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
163 reg = <0x02018000 0x4000>;
164 interrupts = <0 35 0x04>;
165 status = "disabled";
166 };
167
168 uart0: uart@02020000 { /* UART1 */
169 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
170 reg = <0x02020000 0x4000>;
171 interrupts = <0 26 0x04>;
172 status = "disabled";
173 };
174
175 esai@02024000 {
176 reg = <0x02024000 0x4000>;
177 interrupts = <0 51 0x04>;
178 };
179
180 ssi@02028000 { /* SSI1 */
181 reg = <0x02028000 0x4000>;
182 interrupts = <0 46 0x04>;
183 };
184
185 ssi@0202c000 { /* SSI2 */
186 reg = <0x0202c000 0x4000>;
187 interrupts = <0 47 0x04>;
188 };
189
190 ssi@02030000 { /* SSI3 */
191 reg = <0x02030000 0x4000>;
192 interrupts = <0 48 0x04>;
193 };
194
195 asrc@02034000 {
196 reg = <0x02034000 0x4000>;
197 interrupts = <0 50 0x04>;
198 };
199
200 spba@0203c000 {
201 reg = <0x0203c000 0x4000>;
202 };
203 };
204
205 vpu@02040000 {
206 reg = <0x02040000 0x3c000>;
207 interrupts = <0 3 0x04 0 12 0x04>;
208 };
209
210 aipstz@0207c000 { /* AIPSTZ1 */
211 reg = <0x0207c000 0x4000>;
212 };
213
214 pwm@02080000 { /* PWM1 */
215 reg = <0x02080000 0x4000>;
216 interrupts = <0 83 0x04>;
217 };
218
219 pwm@02084000 { /* PWM2 */
220 reg = <0x02084000 0x4000>;
221 interrupts = <0 84 0x04>;
222 };
223
224 pwm@02088000 { /* PWM3 */
225 reg = <0x02088000 0x4000>;
226 interrupts = <0 85 0x04>;
227 };
228
229 pwm@0208c000 { /* PWM4 */
230 reg = <0x0208c000 0x4000>;
231 interrupts = <0 86 0x04>;
232 };
233
234 flexcan@02090000 { /* CAN1 */
235 reg = <0x02090000 0x4000>;
236 interrupts = <0 110 0x04>;
237 };
238
239 flexcan@02094000 { /* CAN2 */
240 reg = <0x02094000 0x4000>;
241 interrupts = <0 111 0x04>;
242 };
243
244 gpt@02098000 {
245 compatible = "fsl,imx6q-gpt";
246 reg = <0x02098000 0x4000>;
247 interrupts = <0 55 0x04>;
248 };
249
250 gpio0: gpio@0209c000 { /* GPIO1 */
251 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
252 reg = <0x0209c000 0x4000>;
253 interrupts = <0 66 0x04 0 67 0x04>;
254 gpio-controller;
255 #gpio-cells = <2>;
256 interrupt-controller;
257 #interrupt-cells = <1>;
258 };
259
260 gpio1: gpio@020a0000 { /* GPIO2 */
261 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
262 reg = <0x020a0000 0x4000>;
263 interrupts = <0 68 0x04 0 69 0x04>;
264 gpio-controller;
265 #gpio-cells = <2>;
266 interrupt-controller;
267 #interrupt-cells = <1>;
268 };
269
270 gpio2: gpio@020a4000 { /* GPIO3 */
271 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
272 reg = <0x020a4000 0x4000>;
273 interrupts = <0 70 0x04 0 71 0x04>;
274 gpio-controller;
275 #gpio-cells = <2>;
276 interrupt-controller;
277 #interrupt-cells = <1>;
278 };
279
280 gpio3: gpio@020a8000 { /* GPIO4 */
281 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
282 reg = <0x020a8000 0x4000>;
283 interrupts = <0 72 0x04 0 73 0x04>;
284 gpio-controller;
285 #gpio-cells = <2>;
286 interrupt-controller;
287 #interrupt-cells = <1>;
288 };
289
290 gpio4: gpio@020ac000 { /* GPIO5 */
291 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
292 reg = <0x020ac000 0x4000>;
293 interrupts = <0 74 0x04 0 75 0x04>;
294 gpio-controller;
295 #gpio-cells = <2>;
296 interrupt-controller;
297 #interrupt-cells = <1>;
298 };
299
300 gpio5: gpio@020b0000 { /* GPIO6 */
301 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
302 reg = <0x020b0000 0x4000>;
303 interrupts = <0 76 0x04 0 77 0x04>;
304 gpio-controller;
305 #gpio-cells = <2>;
306 interrupt-controller;
307 #interrupt-cells = <1>;
308 };
309
310 gpio6: gpio@020b4000 { /* GPIO7 */
311 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
312 reg = <0x020b4000 0x4000>;
313 interrupts = <0 78 0x04 0 79 0x04>;
314 gpio-controller;
315 #gpio-cells = <2>;
316 interrupt-controller;
317 #interrupt-cells = <1>;
318 };
319
320 kpp@020b8000 {
321 reg = <0x020b8000 0x4000>;
322 interrupts = <0 82 0x04>;
323 };
324
325 wdog@020bc000 { /* WDOG1 */
326 compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
327 reg = <0x020bc000 0x4000>;
328 interrupts = <0 80 0x04>;
329 status = "disabled";
330 };
331
332 wdog@020c0000 { /* WDOG2 */
333 compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
334 reg = <0x020c0000 0x4000>;
335 interrupts = <0 81 0x04>;
336 status = "disabled";
337 };
338
339 ccm@020c4000 {
340 compatible = "fsl,imx6q-ccm";
341 reg = <0x020c4000 0x4000>;
342 interrupts = <0 87 0x04 0 88 0x04>;
343 };
344
345 anatop@020c8000 {
346 compatible = "fsl,imx6q-anatop";
347 reg = <0x020c8000 0x1000>;
348 interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
349 };
350
351 usbphy@020c9000 { /* USBPHY1 */
352 reg = <0x020c9000 0x1000>;
353 interrupts = <0 44 0x04>;
354 };
355
356 usbphy@020ca000 { /* USBPHY2 */
357 reg = <0x020ca000 0x1000>;
358 interrupts = <0 45 0x04>;
359 };
360
361 snvs@020cc000 {
362 reg = <0x020cc000 0x4000>;
363 interrupts = <0 19 0x04 0 20 0x04>;
364 };
365
366 epit@020d0000 { /* EPIT1 */
367 reg = <0x020d0000 0x4000>;
368 interrupts = <0 56 0x04>;
369 };
370
371 epit@020d4000 { /* EPIT2 */
372 reg = <0x020d4000 0x4000>;
373 interrupts = <0 57 0x04>;
374 };
375
376 src@020d8000 {
377 compatible = "fsl,imx6q-src";
378 reg = <0x020d8000 0x4000>;
379 interrupts = <0 91 0x04 0 96 0x04>;
380 };
381
382 gpc@020dc000 {
383 compatible = "fsl,imx6q-gpc";
384 reg = <0x020dc000 0x4000>;
385 interrupts = <0 89 0x04 0 90 0x04>;
386 };
387
388 iomuxc@020e0000 {
389 reg = <0x020e0000 0x4000>;
390 };
391
392 dcic@020e4000 { /* DCIC1 */
393 reg = <0x020e4000 0x4000>;
394 interrupts = <0 124 0x04>;
395 };
396
397 dcic@020e8000 { /* DCIC2 */
398 reg = <0x020e8000 0x4000>;
399 interrupts = <0 125 0x04>;
400 };
401
402 sdma@020ec000 {
403 compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
404 reg = <0x020ec000 0x4000>;
405 interrupts = <0 2 0x04>;
406 };
407 };
408
409 aips-bus@02100000 { /* AIPS2 */
410 compatible = "fsl,aips-bus", "simple-bus";
411 #address-cells = <1>;
412 #size-cells = <1>;
413 reg = <0x02100000 0x100000>;
414 ranges;
415
416 caam@02100000 {
417 reg = <0x02100000 0x40000>;
418 interrupts = <0 105 0x04 0 106 0x04>;
419 };
420
421 aipstz@0217c000 { /* AIPSTZ2 */
422 reg = <0x0217c000 0x4000>;
423 };
424
425 enet@02188000 {
426 compatible = "fsl,imx6q-fec";
427 reg = <0x02188000 0x4000>;
428 interrupts = <0 118 0x04 0 119 0x04>;
429 status = "disabled";
430 };
431
432 mlb@0218c000 {
433 reg = <0x0218c000 0x4000>;
434 interrupts = <0 53 0x04 0 117 0x04 0 126 0x04>;
435 };
436
437 usdhc@02190000 { /* uSDHC1 */
438 compatible = "fsl,imx6q-usdhc";
439 reg = <0x02190000 0x4000>;
440 interrupts = <0 22 0x04>;
441 status = "disabled";
442 };
443
444 usdhc@02194000 { /* uSDHC2 */
445 compatible = "fsl,imx6q-usdhc";
446 reg = <0x02194000 0x4000>;
447 interrupts = <0 23 0x04>;
448 status = "disabled";
449 };
450
451 usdhc@02198000 { /* uSDHC3 */
452 compatible = "fsl,imx6q-usdhc";
453 reg = <0x02198000 0x4000>;
454 interrupts = <0 24 0x04>;
455 status = "disabled";
456 };
457
458 usdhc@0219c000 { /* uSDHC4 */
459 compatible = "fsl,imx6q-usdhc";
460 reg = <0x0219c000 0x4000>;
461 interrupts = <0 25 0x04>;
462 status = "disabled";
463 };
464
465 i2c@021a0000 { /* I2C1 */
466 #address-cells = <1>;
467 #size-cells = <0>;
468 compatible = "fsl,imx6q-i2c", "fsl,imx1-i2c";
469 reg = <0x021a0000 0x4000>;
470 interrupts = <0 36 0x04>;
471 status = "disabled";
472 };
473
474 i2c@021a4000 { /* I2C2 */
475 #address-cells = <1>;
476 #size-cells = <0>;
477 compatible = "fsl,imx6q-i2c", "fsl,imx1-i2c";
478 reg = <0x021a4000 0x4000>;
479 interrupts = <0 37 0x04>;
480 status = "disabled";
481 };
482
483 i2c@021a8000 { /* I2C3 */
484 #address-cells = <1>;
485 #size-cells = <0>;
486 compatible = "fsl,imx6q-i2c", "fsl,imx1-i2c";
487 reg = <0x021a8000 0x4000>;
488 interrupts = <0 38 0x04>;
489 status = "disabled";
490 };
491
492 romcp@021ac000 {
493 reg = <0x021ac000 0x4000>;
494 };
495
496 mmdc@021b0000 { /* MMDC0 */
497 compatible = "fsl,imx6q-mmdc";
498 reg = <0x021b0000 0x4000>;
499 };
500
501 mmdc@021b4000 { /* MMDC1 */
502 reg = <0x021b4000 0x4000>;
503 };
504
505 weim@021b8000 {
506 reg = <0x021b8000 0x4000>;
507 interrupts = <0 14 0x04>;
508 };
509
510 ocotp@021bc000 {
511 reg = <0x021bc000 0x4000>;
512 };
513
514 ocotp@021c0000 {
515 reg = <0x021c0000 0x4000>;
516 interrupts = <0 21 0x04>;
517 };
518
519 tzasc@021d0000 { /* TZASC1 */
520 reg = <0x021d0000 0x4000>;
521 interrupts = <0 108 0x04>;
522 };
523
524 tzasc@021d4000 { /* TZASC2 */
525 reg = <0x021d4000 0x4000>;
526 interrupts = <0 109 0x04>;
527 };
528
529 audmux@021d8000 {
530 reg = <0x021d8000 0x4000>;
531 };
532
533 mipi@021dc000 { /* MIPI-CSI */
534 reg = <0x021dc000 0x4000>;
535 };
536
537 mipi@021e0000 { /* MIPI-DSI */
538 reg = <0x021e0000 0x4000>;
539 };
540
541 vdoa@021e4000 {
542 reg = <0x021e4000 0x4000>;
543 interrupts = <0 18 0x04>;
544 };
545
546 uart1: uart@021e8000 { /* UART2 */
547 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
548 reg = <0x021e8000 0x4000>;
549 interrupts = <0 27 0x04>;
550 status = "disabled";
551 };
552
553 uart2: uart@021ec000 { /* UART3 */
554 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
555 reg = <0x021ec000 0x4000>;
556 interrupts = <0 28 0x04>;
557 status = "disabled";
558 };
559
560 uart3: uart@021f0000 { /* UART4 */
561 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
562 reg = <0x021f0000 0x4000>;
563 interrupts = <0 29 0x04>;
564 status = "disabled";
565 };
566
567 uart4: uart@021f4000 { /* UART5 */
568 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
569 reg = <0x021f4000 0x4000>;
570 interrupts = <0 30 0x04>;
571 status = "disabled";
572 };
573 };
574 };
575};
diff --git a/arch/arm/boot/dts/picoxcell-pc3x2.dtsi b/arch/arm/boot/dts/picoxcell-pc3x2.dtsi
new file mode 100644
index 000000000000..f0a8c2068ea7
--- /dev/null
+++ b/arch/arm/boot/dts/picoxcell-pc3x2.dtsi
@@ -0,0 +1,249 @@
1/*
2 * Copyright (C) 2011 Picochip, Jamie Iles
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13/include/ "skeleton.dtsi"
14/ {
15 model = "Picochip picoXcell PC3X2";
16 compatible = "picochip,pc3x2";
17 #address-cells = <1>;
18 #size-cells = <1>;
19
20 cpus {
21 #address-cells = <1>;
22 #size-cells = <0>;
23
24 cpu@0 {
25 compatible = "arm,1176jz-s";
26 clock-frequency = <400000000>;
27 reg = <0>;
28 d-cache-line-size = <32>;
29 d-cache-size = <32768>;
30 i-cache-line-size = <32>;
31 i-cache-size = <32768>;
32 };
33 };
34
35 clocks {
36 #address-cells = <1>;
37 #size-cells = <1>;
38 ranges;
39
40 pclk: clock@0 {
41 compatible = "fixed-clock";
42 clock-outputs = "bus", "pclk";
43 clock-frequency = <200000000>;
44 ref-clock = <&ref_clk>, "ref";
45 };
46 };
47
48 paxi {
49 compatible = "simple-bus";
50 #address-cells = <1>;
51 #size-cells = <1>;
52 ranges = <0 0x80000000 0x400000>;
53
54 emac: gem@30000 {
55 compatible = "cadence,gem";
56 reg = <0x30000 0x10000>;
57 interrupts = <31>;
58 };
59
60 dmac1: dmac@40000 {
61 compatible = "snps,dw-dmac";
62 reg = <0x40000 0x10000>;
63 interrupts = <25>;
64 };
65
66 dmac2: dmac@50000 {
67 compatible = "snps,dw-dmac";
68 reg = <0x50000 0x10000>;
69 interrupts = <26>;
70 };
71
72 vic0: interrupt-controller@60000 {
73 compatible = "arm,pl192-vic";
74 interrupt-controller;
75 reg = <0x60000 0x1000>;
76 #interrupt-cells = <1>;
77 };
78
79 vic1: interrupt-controller@64000 {
80 compatible = "arm,pl192-vic";
81 interrupt-controller;
82 reg = <0x64000 0x1000>;
83 #interrupt-cells = <1>;
84 };
85
86 fuse: picoxcell-fuse@80000 {
87 compatible = "picoxcell,fuse-pc3x2";
88 reg = <0x80000 0x10000>;
89 };
90
91 ssi: picoxcell-spi@90000 {
92 compatible = "picoxcell,spi";
93 reg = <0x90000 0x10000>;
94 interrupt-parent = <&vic0>;
95 interrupts = <10>;
96 };
97
98 ipsec: spacc@100000 {
99 compatible = "picochip,spacc-ipsec";
100 reg = <0x100000 0x10000>;
101 interrupt-parent = <&vic0>;
102 interrupts = <24>;
103 ref-clock = <&pclk>, "ref";
104 };
105
106 srtp: spacc@140000 {
107 compatible = "picochip,spacc-srtp";
108 reg = <0x140000 0x10000>;
109 interrupt-parent = <&vic0>;
110 interrupts = <23>;
111 };
112
113 l2_engine: spacc@180000 {
114 compatible = "picochip,spacc-l2";
115 reg = <0x180000 0x10000>;
116 interrupt-parent = <&vic0>;
117 interrupts = <22>;
118 ref-clock = <&pclk>, "ref";
119 };
120
121 apb {
122 compatible = "simple-bus";
123 #address-cells = <1>;
124 #size-cells = <1>;
125 ranges = <0 0x200000 0x80000>;
126
127 rtc0: rtc@00000 {
128 compatible = "picochip,pc3x2-rtc";
129 clock-freq = <200000000>;
130 reg = <0x00000 0xf>;
131 interrupt-parent = <&vic1>;
132 interrupts = <8>;
133 };
134
135 timer0: timer@10000 {
136 compatible = "picochip,pc3x2-timer";
137 interrupt-parent = <&vic0>;
138 interrupts = <4>;
139 clock-freq = <200000000>;
140 reg = <0x10000 0x14>;
141 };
142
143 timer1: timer@10014 {
144 compatible = "picochip,pc3x2-timer";
145 interrupt-parent = <&vic0>;
146 interrupts = <5>;
147 clock-freq = <200000000>;
148 reg = <0x10014 0x14>;
149 };
150
151 timer2: timer@10028 {
152 compatible = "picochip,pc3x2-timer";
153 interrupt-parent = <&vic0>;
154 interrupts = <6>;
155 clock-freq = <200000000>;
156 reg = <0x10028 0x14>;
157 };
158
159 timer3: timer@1003c {
160 compatible = "picochip,pc3x2-timer";
161 interrupt-parent = <&vic0>;
162 interrupts = <7>;
163 clock-freq = <200000000>;
164 reg = <0x1003c 0x14>;
165 };
166
167 gpio: gpio@20000 {
168 compatible = "snps,dw-apb-gpio";
169 reg = <0x20000 0x1000>;
170 #address-cells = <1>;
171 #size-cells = <0>;
172 reg-io-width = <4>;
173
174 banka: gpio-controller@0 {
175 compatible = "snps,dw-apb-gpio-bank";
176 gpio-controller;
177 #gpio-cells = <2>;
178 gpio-generic,nr-gpio = <8>;
179
180 regoffset-dat = <0x50>;
181 regoffset-set = <0x00>;
182 regoffset-dirout = <0x04>;
183 };
184
185 bankb: gpio-controller@1 {
186 compatible = "snps,dw-apb-gpio-bank";
187 gpio-controller;
188 #gpio-cells = <2>;
189 gpio-generic,nr-gpio = <8>;
190
191 regoffset-dat = <0x54>;
192 regoffset-set = <0x0c>;
193 regoffset-dirout = <0x10>;
194 };
195 };
196
197 uart0: uart@30000 {
198 compatible = "snps,dw-apb-uart";
199 reg = <0x30000 0x1000>;
200 interrupt-parent = <&vic1>;
201 interrupts = <10>;
202 clock-frequency = <3686400>;
203 reg-shift = <2>;
204 reg-io-width = <4>;
205 };
206
207 uart1: uart@40000 {
208 compatible = "snps,dw-apb-uart";
209 reg = <0x40000 0x1000>;
210 interrupt-parent = <&vic1>;
211 interrupts = <9>;
212 clock-frequency = <3686400>;
213 reg-shift = <2>;
214 reg-io-width = <4>;
215 };
216
217 wdog: watchdog@50000 {
218 compatible = "snps,dw-apb-wdg";
219 reg = <0x50000 0x10000>;
220 interrupt-parent = <&vic0>;
221 interrupts = <11>;
222 bus-clock = <&pclk>, "bus";
223 };
224 };
225 };
226
227 rwid-axi {
228 #address-cells = <1>;
229 #size-cells = <1>;
230 compatible = "simple-bus";
231 ranges;
232
233 ebi@50000000 {
234 compatible = "simple-bus";
235 #address-cells = <2>;
236 #size-cells = <1>;
237 ranges = <0 0 0x40000000 0x08000000
238 1 0 0x48000000 0x08000000
239 2 0 0x50000000 0x08000000
240 3 0 0x58000000 0x08000000>;
241 };
242
243 axi2pico@c0000000 {
244 compatible = "picochip,axi2pico-pc3x2";
245 reg = <0xc0000000 0x10000>;
246 interrupts = <13 14 15 16 17 18 19 20 21>;
247 };
248 };
249};
diff --git a/arch/arm/boot/dts/picoxcell-pc3x3.dtsi b/arch/arm/boot/dts/picoxcell-pc3x3.dtsi
new file mode 100644
index 000000000000..daa962d191e6
--- /dev/null
+++ b/arch/arm/boot/dts/picoxcell-pc3x3.dtsi
@@ -0,0 +1,365 @@
1/*
2 * Copyright (C) 2011 Picochip, Jamie Iles
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13/include/ "skeleton.dtsi"
14/ {
15 model = "Picochip picoXcell PC3X3";
16 compatible = "picochip,pc3x3";
17 #address-cells = <1>;
18 #size-cells = <1>;
19
20 cpus {
21 #address-cells = <1>;
22 #size-cells = <0>;
23
24 cpu@0 {
25 compatible = "arm,1176jz-s";
26 cpu-clock = <&arm_clk>, "cpu";
27 reg = <0>;
28 d-cache-line-size = <32>;
29 d-cache-size = <32768>;
30 i-cache-line-size = <32>;
31 i-cache-size = <32768>;
32 };
33 };
34
35 clocks {
36 #address-cells = <1>;
37 #size-cells = <1>;
38 ranges;
39
40 clkgate: clkgate@800a0048 {
41 #address-cells = <1>;
42 #size-cells = <0>;
43 reg = <0x800a0048 4>;
44 compatible = "picochip,pc3x3-clk-gate";
45
46 tzprot_clk: clock@0 {
47 compatible = "picochip,pc3x3-gated-clk";
48 clock-outputs = "bus";
49 picochip,clk-disable-bit = <0>;
50 clock-frequency = <200000000>;
51 ref-clock = <&ref_clk>, "ref";
52 };
53
54 spi_clk: clock@1 {
55 compatible = "picochip,pc3x3-gated-clk";
56 clock-outputs = "bus";
57 picochip,clk-disable-bit = <1>;
58 clock-frequency = <200000000>;
59 ref-clock = <&ref_clk>, "ref";
60 };
61
62 dmac0_clk: clock@2 {
63 compatible = "picochip,pc3x3-gated-clk";
64 clock-outputs = "bus";
65 picochip,clk-disable-bit = <2>;
66 clock-frequency = <200000000>;
67 ref-clock = <&ref_clk>, "ref";
68 };
69
70 dmac1_clk: clock@3 {
71 compatible = "picochip,pc3x3-gated-clk";
72 clock-outputs = "bus";
73 picochip,clk-disable-bit = <3>;
74 clock-frequency = <200000000>;
75 ref-clock = <&ref_clk>, "ref";
76 };
77
78 ebi_clk: clock@4 {
79 compatible = "picochip,pc3x3-gated-clk";
80 clock-outputs = "bus";
81 picochip,clk-disable-bit = <4>;
82 clock-frequency = <200000000>;
83 ref-clock = <&ref_clk>, "ref";
84 };
85
86 ipsec_clk: clock@5 {
87 compatible = "picochip,pc3x3-gated-clk";
88 clock-outputs = "bus";
89 picochip,clk-disable-bit = <5>;
90 clock-frequency = <200000000>;
91 ref-clock = <&ref_clk>, "ref";
92 };
93
94 l2_clk: clock@6 {
95 compatible = "picochip,pc3x3-gated-clk";
96 clock-outputs = "bus";
97 picochip,clk-disable-bit = <6>;
98 clock-frequency = <200000000>;
99 ref-clock = <&ref_clk>, "ref";
100 };
101
102 trng_clk: clock@7 {
103 compatible = "picochip,pc3x3-gated-clk";
104 clock-outputs = "bus";
105 picochip,clk-disable-bit = <7>;
106 clock-frequency = <200000000>;
107 ref-clock = <&ref_clk>, "ref";
108 };
109
110 fuse_clk: clock@8 {
111 compatible = "picochip,pc3x3-gated-clk";
112 clock-outputs = "bus";
113 picochip,clk-disable-bit = <8>;
114 clock-frequency = <200000000>;
115 ref-clock = <&ref_clk>, "ref";
116 };
117
118 otp_clk: clock@9 {
119 compatible = "picochip,pc3x3-gated-clk";
120 clock-outputs = "bus";
121 picochip,clk-disable-bit = <9>;
122 clock-frequency = <200000000>;
123 ref-clock = <&ref_clk>, "ref";
124 };
125 };
126
127 arm_clk: clock@11 {
128 compatible = "picochip,pc3x3-pll";
129 reg = <0x800a0050 0x8>;
130 picochip,min-freq = <140000000>;
131 picochip,max-freq = <700000000>;
132 ref-clock = <&ref_clk>, "ref";
133 clock-outputs = "cpu";
134 };
135
136 pclk: clock@12 {
137 compatible = "fixed-clock";
138 clock-outputs = "bus", "pclk";
139 clock-frequency = <200000000>;
140 ref-clock = <&ref_clk>, "ref";
141 };
142 };
143
144 paxi {
145 compatible = "simple-bus";
146 #address-cells = <1>;
147 #size-cells = <1>;
148 ranges = <0 0x80000000 0x400000>;
149
150 emac: gem@30000 {
151 compatible = "cadence,gem";
152 reg = <0x30000 0x10000>;
153 interrupt-parent = <&vic0>;
154 interrupts = <31>;
155 };
156
157 dmac1: dmac@40000 {
158 compatible = "snps,dw-dmac";
159 reg = <0x40000 0x10000>;
160 interrupt-parent = <&vic0>;
161 interrupts = <25>;
162 };
163
164 dmac2: dmac@50000 {
165 compatible = "snps,dw-dmac";
166 reg = <0x50000 0x10000>;
167 interrupt-parent = <&vic0>;
168 interrupts = <26>;
169 };
170
171 vic0: interrupt-controller@60000 {
172 compatible = "arm,pl192-vic";
173 interrupt-controller;
174 reg = <0x60000 0x1000>;
175 #interrupt-cells = <1>;
176 };
177
178 vic1: interrupt-controller@64000 {
179 compatible = "arm,pl192-vic";
180 interrupt-controller;
181 reg = <0x64000 0x1000>;
182 #interrupt-cells = <1>;
183 };
184
185 fuse: picoxcell-fuse@80000 {
186 compatible = "picoxcell,fuse-pc3x3";
187 reg = <0x80000 0x10000>;
188 };
189
190 ssi: picoxcell-spi@90000 {
191 compatible = "picoxcell,spi";
192 reg = <0x90000 0x10000>;
193 interrupt-parent = <&vic0>;
194 interrupts = <10>;
195 };
196
197 ipsec: spacc@100000 {
198 compatible = "picochip,spacc-ipsec";
199 reg = <0x100000 0x10000>;
200 interrupt-parent = <&vic0>;
201 interrupts = <24>;
202 ref-clock = <&ipsec_clk>, "ref";
203 };
204
205 srtp: spacc@140000 {
206 compatible = "picochip,spacc-srtp";
207 reg = <0x140000 0x10000>;
208 interrupt-parent = <&vic0>;
209 interrupts = <23>;
210 };
211
212 l2_engine: spacc@180000 {
213 compatible = "picochip,spacc-l2";
214 reg = <0x180000 0x10000>;
215 interrupt-parent = <&vic0>;
216 interrupts = <22>;
217 ref-clock = <&l2_clk>, "ref";
218 };
219
220 apb {
221 compatible = "simple-bus";
222 #address-cells = <1>;
223 #size-cells = <1>;
224 ranges = <0 0x200000 0x80000>;
225
226 rtc0: rtc@00000 {
227 compatible = "picochip,pc3x2-rtc";
228 clock-freq = <200000000>;
229 reg = <0x00000 0xf>;
230 interrupt-parent = <&vic0>;
231 interrupts = <8>;
232 };
233
234 timer0: timer@10000 {
235 compatible = "picochip,pc3x2-timer";
236 interrupt-parent = <&vic0>;
237 interrupts = <4>;
238 clock-freq = <200000000>;
239 reg = <0x10000 0x14>;
240 };
241
242 timer1: timer@10014 {
243 compatible = "picochip,pc3x2-timer";
244 interrupt-parent = <&vic0>;
245 interrupts = <5>;
246 clock-freq = <200000000>;
247 reg = <0x10014 0x14>;
248 };
249
250 gpio: gpio@20000 {
251 compatible = "snps,dw-apb-gpio";
252 reg = <0x20000 0x1000>;
253 #address-cells = <1>;
254 #size-cells = <0>;
255 reg-io-width = <4>;
256
257 banka: gpio-controller@0 {
258 compatible = "snps,dw-apb-gpio-bank";
259 gpio-controller;
260 #gpio-cells = <2>;
261 gpio-generic,nr-gpio = <8>;
262
263 regoffset-dat = <0x50>;
264 regoffset-set = <0x00>;
265 regoffset-dirout = <0x04>;
266 };
267
268 bankb: gpio-controller@1 {
269 compatible = "snps,dw-apb-gpio-bank";
270 gpio-controller;
271 #gpio-cells = <2>;
272 gpio-generic,nr-gpio = <16>;
273
274 regoffset-dat = <0x54>;
275 regoffset-set = <0x0c>;
276 regoffset-dirout = <0x10>;
277 };
278
279 bankd: gpio-controller@2 {
280 compatible = "snps,dw-apb-gpio-bank";
281 gpio-controller;
282 #gpio-cells = <2>;
283 gpio-generic,nr-gpio = <30>;
284
285 regoffset-dat = <0x5c>;
286 regoffset-set = <0x24>;
287 regoffset-dirout = <0x28>;
288 };
289 };
290
291 uart0: uart@30000 {
292 compatible = "snps,dw-apb-uart";
293 reg = <0x30000 0x1000>;
294 interrupt-parent = <&vic1>;
295 interrupts = <10>;
296 clock-frequency = <3686400>;
297 reg-shift = <2>;
298 reg-io-width = <4>;
299 };
300
301 uart1: uart@40000 {
302 compatible = "snps,dw-apb-uart";
303 reg = <0x40000 0x1000>;
304 interrupt-parent = <&vic1>;
305 interrupts = <9>;
306 clock-frequency = <3686400>;
307 reg-shift = <2>;
308 reg-io-width = <4>;
309 };
310
311 wdog: watchdog@50000 {
312 compatible = "snps,dw-apb-wdg";
313 reg = <0x50000 0x10000>;
314 interrupt-parent = <&vic0>;
315 interrupts = <11>;
316 bus-clock = <&pclk>, "bus";
317 };
318
319 timer2: timer@60000 {
320 compatible = "picochip,pc3x2-timer";
321 interrupt-parent = <&vic0>;
322 interrupts = <6>;
323 clock-freq = <200000000>;
324 reg = <0x60000 0x14>;
325 };
326
327 timer3: timer@60014 {
328 compatible = "picochip,pc3x2-timer";
329 interrupt-parent = <&vic0>;
330 interrupts = <7>;
331 clock-freq = <200000000>;
332 reg = <0x60014 0x14>;
333 };
334 };
335 };
336
337 rwid-axi {
338 #address-cells = <1>;
339 #size-cells = <1>;
340 compatible = "simple-bus";
341 ranges;
342
343 ebi@50000000 {
344 compatible = "simple-bus";
345 #address-cells = <2>;
346 #size-cells = <1>;
347 ranges = <0 0 0x40000000 0x08000000
348 1 0 0x48000000 0x08000000
349 2 0 0x50000000 0x08000000
350 3 0 0x58000000 0x08000000>;
351 };
352
353 axi2pico@c0000000 {
354 compatible = "picochip,axi2pico-pc3x3";
355 reg = <0xc0000000 0x10000>;
356 interrupt-parent = <&vic0>;
357 interrupts = <13 14 15 16 17 18 19 20 21>;
358 };
359
360 otp@ffff8000 {
361 compatible = "picochip,otp-pc3x3";
362 reg = <0xffff8000 0x8000>;
363 };
364 };
365};
diff --git a/arch/arm/boot/dts/picoxcell-pc7302-pc3x2.dts b/arch/arm/boot/dts/picoxcell-pc7302-pc3x2.dts
new file mode 100644
index 000000000000..1297414dd649
--- /dev/null
+++ b/arch/arm/boot/dts/picoxcell-pc7302-pc3x2.dts
@@ -0,0 +1,86 @@
1/*
2 * Copyright (C) 2011 Picochip, Jamie Iles
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14/dts-v1/;
15/include/ "picoxcell-pc3x2.dtsi"
16/ {
17 model = "Picochip PC7302 (PC3X2)";
18 compatible = "picochip,pc7302-pc3x2", "picochip,pc3x2";
19
20 memory {
21 device_type = "memory";
22 reg = <0x0 0x08000000>;
23 };
24
25 chosen {
26 linux,stdout-path = &uart0;
27 };
28
29 clocks {
30 ref_clk: clock@1 {
31 compatible = "fixed-clock";
32 clock-outputs = "ref";
33 clock-frequency = <20000000>;
34 };
35 };
36
37 rwid-axi {
38 ebi@50000000 {
39 nand: gpio-nand@2,0 {
40 compatible = "gpio-control-nand";
41 #address-cells = <1>;
42 #size-cells = <1>;
43 reg = <2 0x0000 0x1000>;
44 bus-clock = <&pclk>, "bus";
45 gpio-control-nand,io-sync-reg =
46 <0x00000000 0x80220000>;
47
48 gpios = <&banka 1 0 /* rdy */
49 &banka 2 0 /* nce */
50 &banka 3 0 /* ale */
51 &banka 4 0 /* cle */
52 0 /* nwp */>;
53
54 boot@100000 {
55 label = "Boot";
56 reg = <0x100000 0x80000>;
57 };
58
59 redundant-boot@200000 {
60 label = "Redundant Boot";
61 reg = <0x200000 0x80000>;
62 };
63
64 boot-env@300000 {
65 label = "Boot Evironment";
66 reg = <0x300000 0x20000>;
67 };
68
69 redundant-boot-env@320000 {
70 label = "Redundant Boot Environment";
71 reg = <0x300000 0x20000>;
72 };
73
74 kernel@380000 {
75 label = "Kernel";
76 reg = <0x380000 0x800000>;
77 };
78
79 fs@b80000 {
80 label = "File System";
81 reg = <0xb80000 0xf480000>;
82 };
83 };
84 };
85 };
86};
diff --git a/arch/arm/boot/dts/picoxcell-pc7302-pc3x3.dts b/arch/arm/boot/dts/picoxcell-pc7302-pc3x3.dts
new file mode 100644
index 000000000000..9e317a4f431c
--- /dev/null
+++ b/arch/arm/boot/dts/picoxcell-pc7302-pc3x3.dts
@@ -0,0 +1,92 @@
1/*
2 * Copyright (C) 2011 Picochip, Jamie Iles
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14/dts-v1/;
15/include/ "picoxcell-pc3x3.dtsi"
16/ {
17 model = "Picochip PC7302 (PC3X3)";
18 compatible = "picochip,pc7302-pc3x3", "picochip,pc3x3";
19
20 memory {
21 device_type = "memory";
22 reg = <0x0 0x08000000>;
23 };
24
25 chosen {
26 linux,stdout-path = &uart0;
27 };
28
29 clocks {
30 ref_clk: clock@10 {
31 compatible = "fixed-clock";
32 clock-outputs = "ref";
33 clock-frequency = <20000000>;
34 };
35
36 clkgate: clkgate@800a0048 {
37 clock@4 {
38 picochip,clk-no-disable;
39 };
40 };
41 };
42
43 rwid-axi {
44 ebi@50000000 {
45 nand: gpio-nand@2,0 {
46 compatible = "gpio-control-nand";
47 #address-cells = <1>;
48 #size-cells = <1>;
49 reg = <2 0x0000 0x1000>;
50 bus-clock = <&ebi_clk>, "bus";
51 gpio-control-nand,io-sync-reg =
52 <0x00000000 0x80220000>;
53
54 gpios = <&banka 1 0 /* rdy */
55 &banka 2 0 /* nce */
56 &banka 3 0 /* ale */
57 &banka 4 0 /* cle */
58 0 /* nwp */>;
59
60 boot@100000 {
61 label = "Boot";
62 reg = <0x100000 0x80000>;
63 };
64
65 redundant-boot@200000 {
66 label = "Redundant Boot";
67 reg = <0x200000 0x80000>;
68 };
69
70 boot-env@300000 {
71 label = "Boot Evironment";
72 reg = <0x300000 0x20000>;
73 };
74
75 redundant-boot-env@320000 {
76 label = "Redundant Boot Environment";
77 reg = <0x300000 0x20000>;
78 };
79
80 kernel@380000 {
81 label = "Kernel";
82 reg = <0x380000 0x800000>;
83 };
84
85 fs@b80000 {
86 label = "File System";
87 reg = <0xb80000 0xf480000>;
88 };
89 };
90 };
91 };
92};
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 434edccdf7f3..1db1143a9483 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -102,7 +102,14 @@
102 102
103#ifndef __ASSEMBLY__ 103#ifndef __ASSEMBLY__
104extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); 104extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
105#if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF)
105extern int l2x0_of_init(__u32 aux_val, __u32 aux_mask); 106extern int l2x0_of_init(__u32 aux_val, __u32 aux_mask);
107#else
108static inline int l2x0_of_init(__u32 aux_val, __u32 aux_mask)
109{
110 return -ENODEV;
111}
112#endif
106 113
107struct l2x0_regs { 114struct l2x0_regs {
108 unsigned long phy_base; 115 unsigned long phy_base;
@@ -121,6 +128,6 @@ struct l2x0_regs {
121 128
122extern struct l2x0_regs l2x0_saved_regs; 129extern struct l2x0_regs l2x0_saved_regs;
123 130
124#endif 131#endif /* __ASSEMBLY__ */
125 132
126#endif 133#endif
diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile
new file mode 100644
index 000000000000..986958a5a720
--- /dev/null
+++ b/arch/arm/mach-highbank/Makefile
@@ -0,0 +1,6 @@
1obj-y := clock.o highbank.o system.o
2obj-$(CONFIG_DEBUG_HIGHBANK_UART) += lluart.o
3obj-$(CONFIG_SMP) += platsmp.o
4obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
5obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
6obj-$(CONFIG_PM_SLEEP) += pm.o
diff --git a/arch/arm/mach-highbank/Makefile.boot b/arch/arm/mach-highbank/Makefile.boot
new file mode 100644
index 000000000000..dae9661a7689
--- /dev/null
+++ b/arch/arm/mach-highbank/Makefile.boot
@@ -0,0 +1 @@
zreladdr-y := 0x00008000
diff --git a/arch/arm/mach-highbank/clock.c b/arch/arm/mach-highbank/clock.c
new file mode 100644
index 000000000000..c25a2ae4fde1
--- /dev/null
+++ b/arch/arm/mach-highbank/clock.c
@@ -0,0 +1,62 @@
1/*
2 * Copyright 2011 Calxeda, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/errno.h>
19#include <linux/clk.h>
20#include <linux/clkdev.h>
21
22struct clk {
23 unsigned long rate;
24};
25
26int clk_enable(struct clk *clk)
27{
28 return 0;
29}
30
31void clk_disable(struct clk *clk)
32{}
33
34unsigned long clk_get_rate(struct clk *clk)
35{
36 return clk->rate;
37}
38
39long clk_round_rate(struct clk *clk, unsigned long rate)
40{
41 return clk->rate;
42}
43
44int clk_set_rate(struct clk *clk, unsigned long rate)
45{
46 return 0;
47}
48
49static struct clk eclk = { .rate = 200000000 };
50static struct clk pclk = { .rate = 150000000 };
51
52static struct clk_lookup lookups[] = {
53 { .clk = &pclk, .con_id = "apb_pclk", },
54 { .clk = &pclk, .dev_id = "sp804", },
55 { .clk = &eclk, .dev_id = "ffe0e000.sdhci", },
56 { .clk = &pclk, .dev_id = "fff36000.serial", },
57};
58
59void __init highbank_clocks_init(void)
60{
61 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
62}
diff --git a/arch/arm/mach-highbank/core.h b/arch/arm/mach-highbank/core.h
new file mode 100644
index 000000000000..7e33fc94cd1e
--- /dev/null
+++ b/arch/arm/mach-highbank/core.h
@@ -0,0 +1,9 @@
1extern void highbank_set_cpu_jump(int cpu, void *jump_addr);
2extern void highbank_clocks_init(void);
3extern void __iomem *scu_base_addr;
4#ifdef CONFIG_DEBUG_HIGHBANK_UART
5extern void highbank_lluart_map_io(void);
6#else
7static inline void highbank_lluart_map_io(void) {}
8#endif
9
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
new file mode 100644
index 000000000000..b82dcf08e747
--- /dev/null
+++ b/arch/arm/mach-highbank/highbank.c
@@ -0,0 +1,145 @@
1/*
2 * Copyright 2010-2011 Calxeda, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include <linux/clk.h>
17#include <linux/clkdev.h>
18#include <linux/io.h>
19#include <linux/irq.h>
20#include <linux/irqdomain.h>
21#include <linux/of.h>
22#include <linux/of_irq.h>
23#include <linux/of_platform.h>
24#include <linux/of_address.h>
25
26#include <asm/cacheflush.h>
27#include <asm/unified.h>
28#include <asm/smp_scu.h>
29#include <asm/hardware/arm_timer.h>
30#include <asm/hardware/timer-sp.h>
31#include <asm/hardware/gic.h>
32#include <asm/hardware/cache-l2x0.h>
33#include <asm/mach/arch.h>
34#include <asm/mach/map.h>
35#include <asm/mach/time.h>
36#include <mach/irqs.h>
37
38#include "core.h"
39#include "sysregs.h"
40
41void __iomem *sregs_base;
42
43#define HB_SCU_VIRT_BASE 0xfee00000
44void __iomem *scu_base_addr = ((void __iomem *)(HB_SCU_VIRT_BASE));
45
46static struct map_desc scu_io_desc __initdata = {
47 .virtual = HB_SCU_VIRT_BASE,
48 .pfn = 0, /* run-time */
49 .length = SZ_4K,
50 .type = MT_DEVICE,
51};
52
53static void __init highbank_scu_map_io(void)
54{
55 unsigned long base;
56
57 /* Get SCU base */
58 asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
59
60 scu_io_desc.pfn = __phys_to_pfn(base);
61 iotable_init(&scu_io_desc, 1);
62}
63
64static void __init highbank_map_io(void)
65{
66 highbank_scu_map_io();
67 highbank_lluart_map_io();
68}
69
70#define HB_JUMP_TABLE_PHYS(cpu) (0x40 + (0x10 * (cpu)))
71#define HB_JUMP_TABLE_VIRT(cpu) phys_to_virt(HB_JUMP_TABLE_PHYS(cpu))
72
73void highbank_set_cpu_jump(int cpu, void *jump_addr)
74{
75 writel(BSYM(virt_to_phys(jump_addr)), HB_JUMP_TABLE_VIRT(cpu));
76 __cpuc_flush_dcache_area(HB_JUMP_TABLE_VIRT(cpu), 16);
77 outer_clean_range(HB_JUMP_TABLE_PHYS(cpu),
78 HB_JUMP_TABLE_PHYS(cpu) + 15);
79}
80
81const static struct of_device_id irq_match[] = {
82 { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
83 {}
84};
85
86static void __init highbank_init_irq(void)
87{
88 of_irq_init(irq_match);
89 l2x0_of_init(0, ~0UL);
90}
91
92static void __init highbank_timer_init(void)
93{
94 int irq;
95 struct device_node *np;
96 void __iomem *timer_base;
97
98 /* Map system registers */
99 np = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs");
100 sregs_base = of_iomap(np, 0);
101 WARN_ON(!sregs_base);
102
103 np = of_find_compatible_node(NULL, NULL, "arm,sp804");
104 timer_base = of_iomap(np, 0);
105 WARN_ON(!timer_base);
106 irq = irq_of_parse_and_map(np, 0);
107
108 highbank_clocks_init();
109
110 sp804_clocksource_init(timer_base + 0x20, "timer1");
111 sp804_clockevents_init(timer_base, irq, "timer0");
112}
113
114static struct sys_timer highbank_timer = {
115 .init = highbank_timer_init,
116};
117
118static void highbank_power_off(void)
119{
120 hignbank_set_pwr_shutdown();
121 scu_power_mode(scu_base_addr, SCU_PM_POWEROFF);
122
123 while (1)
124 cpu_do_idle();
125}
126
127static void __init highbank_init(void)
128{
129 pm_power_off = highbank_power_off;
130
131 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
132}
133
134static const char *highbank_match[] __initconst = {
135 "calxeda,highbank",
136 NULL,
137};
138
139DT_MACHINE_START(HIGHBANK, "Highbank")
140 .map_io = highbank_map_io,
141 .init_irq = highbank_init_irq,
142 .timer = &highbank_timer,
143 .init_machine = highbank_init,
144 .dt_compat = highbank_match,
145MACHINE_END
diff --git a/arch/arm/mach-highbank/hotplug.c b/arch/arm/mach-highbank/hotplug.c
new file mode 100644
index 000000000000..977cebbea580
--- /dev/null
+++ b/arch/arm/mach-highbank/hotplug.c
@@ -0,0 +1,56 @@
1/*
2 * Copyright 2011 Calxeda, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include <linux/kernel.h>
17#include <linux/errno.h>
18#include <linux/smp.h>
19
20#include <asm/smp_scu.h>
21#include <asm/cacheflush.h>
22
23#include "core.h"
24
25extern void secondary_startup(void);
26
27int platform_cpu_kill(unsigned int cpu)
28{
29 return 1;
30}
31
32/*
33 * platform-specific code to shutdown a CPU
34 *
35 */
36void platform_cpu_die(unsigned int cpu)
37{
38 flush_cache_all();
39
40 highbank_set_cpu_jump(cpu, secondary_startup);
41 scu_power_mode(scu_base_addr, SCU_PM_POWEROFF);
42
43 cpu_do_idle();
44
45 /* We should never return from idle */
46 panic("highbank: cpu %d unexpectedly exit from shutdown\n", cpu);
47}
48
49int platform_cpu_disable(unsigned int cpu)
50{
51 /*
52 * CPU0 should not be shut down via hotplug. cpu_idle can WFI
53 * or a proper shutdown or hibernate should be used.
54 */
55 return cpu == 0 ? -EPERM : 0;
56}
diff --git a/arch/arm/mach-highbank/include/mach/debug-macro.S b/arch/arm/mach-highbank/include/mach/debug-macro.S
new file mode 100644
index 000000000000..cb57fe5bcd04
--- /dev/null
+++ b/arch/arm/mach-highbank/include/mach/debug-macro.S
@@ -0,0 +1,19 @@
1/*
2 * Debugging macro include header
3 *
4 * Copyright (C) 1994-1999 Russell King
5 * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12 .macro addruart,rp,rv,tmp
13 movw \rv, #0x6000
14 movt \rv, #0xfee3
15 movw \rp, #0x6000
16 movt \rp, #0xfff3
17 .endm
18
19#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-highbank/include/mach/entry-macro.S b/arch/arm/mach-highbank/include/mach/entry-macro.S
new file mode 100644
index 000000000000..73c11297509e
--- /dev/null
+++ b/arch/arm/mach-highbank/include/mach/entry-macro.S
@@ -0,0 +1,7 @@
1#include <asm/hardware/entry-macro-gic.S>
2
3 .macro disable_fiq
4 .endm
5
6 .macro arch_ret_to_user, tmp1, tmp2
7 .endm
diff --git a/arch/arm/mach-highbank/include/mach/gpio.h b/arch/arm/mach-highbank/include/mach/gpio.h
new file mode 100644
index 000000000000..40a8c178f10d
--- /dev/null
+++ b/arch/arm/mach-highbank/include/mach/gpio.h
@@ -0,0 +1 @@
/* empty */
diff --git a/arch/arm/mach-highbank/include/mach/io.h b/arch/arm/mach-highbank/include/mach/io.h
new file mode 100644
index 000000000000..70cfa3ba7697
--- /dev/null
+++ b/arch/arm/mach-highbank/include/mach/io.h
@@ -0,0 +1,7 @@
1#ifndef __MACH_IO_H
2#define __MACH_IO_H
3
4#define __io(a) ({ (void)(a); __typesafe_io(0); })
5#define __mem_pci(a) (a)
6
7#endif
diff --git a/arch/arm/mach-highbank/include/mach/irqs.h b/arch/arm/mach-highbank/include/mach/irqs.h
new file mode 100644
index 000000000000..9746aab14e9a
--- /dev/null
+++ b/arch/arm/mach-highbank/include/mach/irqs.h
@@ -0,0 +1,6 @@
1#ifndef __MACH_IRQS_H
2#define __MACH_IRQS_H
3
4#define NR_IRQS 192
5
6#endif
diff --git a/arch/arm/mach-highbank/include/mach/memory.h b/arch/arm/mach-highbank/include/mach/memory.h
new file mode 100644
index 000000000000..40a8c178f10d
--- /dev/null
+++ b/arch/arm/mach-highbank/include/mach/memory.h
@@ -0,0 +1 @@
/* empty */
diff --git a/arch/arm/mach-highbank/include/mach/system.h b/arch/arm/mach-highbank/include/mach/system.h
new file mode 100644
index 000000000000..7e8192296cae
--- /dev/null
+++ b/arch/arm/mach-highbank/include/mach/system.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright 2010-2011 Calxeda, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __MACH_SYSTEM_H
17#define __MACH_SYSTEM_H
18
19static inline void arch_idle(void)
20{
21 cpu_do_idle();
22}
23
24extern void arch_reset(char mode, const char *cmd);
25
26#endif
diff --git a/arch/arm/mach-highbank/include/mach/timex.h b/arch/arm/mach-highbank/include/mach/timex.h
new file mode 100644
index 000000000000..88dac7a55a97
--- /dev/null
+++ b/arch/arm/mach-highbank/include/mach/timex.h
@@ -0,0 +1,6 @@
1#ifndef __MACH_TIMEX_H
2#define __MACH_TIMEX_H
3
4#define CLOCK_TICK_RATE 1000000
5
6#endif
diff --git a/arch/arm/mach-highbank/include/mach/uncompress.h b/arch/arm/mach-highbank/include/mach/uncompress.h
new file mode 100644
index 000000000000..bbe20e696325
--- /dev/null
+++ b/arch/arm/mach-highbank/include/mach/uncompress.h
@@ -0,0 +1,9 @@
1#ifndef __MACH_UNCOMPRESS_H
2#define __MACH_UNCOMPRESS_H
3
4#define putc(c)
5#define flush()
6#define arch_decomp_setup()
7#define arch_decomp_wdog()
8
9#endif
diff --git a/arch/arm/mach-highbank/include/mach/vmalloc.h b/arch/arm/mach-highbank/include/mach/vmalloc.h
new file mode 100644
index 000000000000..1969e954277a
--- /dev/null
+++ b/arch/arm/mach-highbank/include/mach/vmalloc.h
@@ -0,0 +1 @@
#define VMALLOC_END 0xFEE00000UL
diff --git a/arch/arm/mach-highbank/lluart.c b/arch/arm/mach-highbank/lluart.c
new file mode 100644
index 000000000000..371575019f33
--- /dev/null
+++ b/arch/arm/mach-highbank/lluart.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright 2011 Calxeda, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include <linux/init.h>
17#include <asm/page.h>
18#include <asm/sizes.h>
19#include <asm/mach/map.h>
20
21#define HB_DEBUG_LL_PHYS_BASE 0xfff36000
22#define HB_DEBUG_LL_VIRT_BASE 0xfee36000
23
24static struct map_desc lluart_io_desc __initdata = {
25 .virtual = HB_DEBUG_LL_VIRT_BASE,
26 .pfn = __phys_to_pfn(HB_DEBUG_LL_PHYS_BASE),
27 .length = SZ_4K,
28 .type = MT_DEVICE,
29};
30
31void __init highbank_lluart_map_io(void)
32{
33 iotable_init(&lluart_io_desc, 1);
34}
diff --git a/arch/arm/mach-highbank/localtimer.c b/arch/arm/mach-highbank/localtimer.c
new file mode 100644
index 000000000000..5a00e7945fdf
--- /dev/null
+++ b/arch/arm/mach-highbank/localtimer.c
@@ -0,0 +1,40 @@
1/*
2 * Copyright 2010-2011 Calxeda, Inc.
3 * Based on localtimer.c, Copyright (C) 2002 ARM Ltd.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17#include <linux/init.h>
18#include <linux/clockchips.h>
19#include <linux/of.h>
20#include <linux/of_address.h>
21#include <linux/of_irq.h>
22
23#include <asm/smp_twd.h>
24
25/*
26 * Setup the local clock events for a CPU.
27 */
28int __cpuinit local_timer_setup(struct clock_event_device *evt)
29{
30 struct device_node *np;
31
32 np = of_find_compatible_node(NULL, NULL, "arm,smp-twd");
33 if (!twd_base) {
34 twd_base = of_iomap(np, 0);
35 WARN_ON(!twd_base);
36 }
37 evt->irq = irq_of_parse_and_map(np, 0);
38 twd_timer_setup(evt);
39 return 0;
40}
diff --git a/arch/arm/mach-highbank/platsmp.c b/arch/arm/mach-highbank/platsmp.c
new file mode 100644
index 000000000000..d01364c72b45
--- /dev/null
+++ b/arch/arm/mach-highbank/platsmp.c
@@ -0,0 +1,78 @@
1/*
2 * Copyright 2010-2011 Calxeda, Inc.
3 * Based on platsmp.c, Copyright (C) 2002 ARM Ltd.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17#include <linux/init.h>
18#include <linux/smp.h>
19#include <linux/io.h>
20
21#include <asm/smp_scu.h>
22#include <asm/hardware/gic.h>
23
24#include "core.h"
25
26extern void secondary_startup(void);
27
28void __cpuinit platform_secondary_init(unsigned int cpu)
29{
30 gic_secondary_init(0);
31}
32
33int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
34{
35 gic_raise_softirq(cpumask_of(cpu), 0);
36 return 0;
37}
38
39/*
40 * Initialise the CPU possible map early - this describes the CPUs
41 * which may be present or become present in the system.
42 */
43void __init smp_init_cpus(void)
44{
45 unsigned int i, ncores;
46
47 ncores = scu_get_core_count(scu_base_addr);
48
49 /* sanity check */
50 if (ncores > NR_CPUS) {
51 printk(KERN_WARNING
52 "highbank: no. of cores (%d) greater than configured "
53 "maximum of %d - clipping\n",
54 ncores, NR_CPUS);
55 ncores = NR_CPUS;
56 }
57
58 for (i = 0; i < ncores; i++)
59 set_cpu_possible(i, true);
60
61 set_smp_cross_call(gic_raise_softirq);
62}
63
64void __init platform_smp_prepare_cpus(unsigned int max_cpus)
65{
66 int i;
67
68 scu_enable(scu_base_addr);
69
70 /*
71 * Write the address of secondary startup into the jump table
72 * The cores are in wfi and wait until they receive a soft interrupt
73 * and a non-zero value to jump to. Then the secondary CPU branches
74 * to this address.
75 */
76 for (i = 1; i < max_cpus; i++)
77 highbank_set_cpu_jump(i, secondary_startup);
78}
diff --git a/arch/arm/mach-highbank/pm.c b/arch/arm/mach-highbank/pm.c
new file mode 100644
index 000000000000..33b3beb89982
--- /dev/null
+++ b/arch/arm/mach-highbank/pm.c
@@ -0,0 +1,55 @@
1/*
2 * Copyright 2011 Calxeda, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/init.h>
18#include <linux/io.h>
19#include <linux/suspend.h>
20
21#include <asm/proc-fns.h>
22#include <asm/smp_scu.h>
23#include <asm/suspend.h>
24
25#include "core.h"
26#include "sysregs.h"
27
28static int highbank_suspend_finish(unsigned long val)
29{
30 cpu_do_idle();
31 return 0;
32}
33
34static int highbank_pm_enter(suspend_state_t state)
35{
36 hignbank_set_pwr_suspend();
37 highbank_set_cpu_jump(0, cpu_resume);
38
39 scu_power_mode(scu_base_addr, SCU_PM_POWEROFF);
40 cpu_suspend(0, highbank_suspend_finish);
41
42 return 0;
43}
44
45static const struct platform_suspend_ops highbank_pm_ops = {
46 .enter = highbank_pm_enter,
47 .valid = suspend_valid_only_mem,
48};
49
50static int __init highbank_pm_init(void)
51{
52 suspend_set_ops(&highbank_pm_ops);
53 return 0;
54}
55module_init(highbank_pm_init);
diff --git a/arch/arm/mach-highbank/sysregs.h b/arch/arm/mach-highbank/sysregs.h
new file mode 100644
index 000000000000..0e913389f445
--- /dev/null
+++ b/arch/arm/mach-highbank/sysregs.h
@@ -0,0 +1,52 @@
1/*
2 * Copyright 2011 Calxeda, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef _MACH_HIGHBANK__SYSREGS_H_
17#define _MACH_HIGHBANK__SYSREGS_H_
18
19#include <linux/io.h>
20
21extern void __iomem *sregs_base;
22
23#define HB_SREG_A9_PWR_REQ 0xf00
24#define HB_SREG_A9_BOOT_STAT 0xf04
25#define HB_SREG_A9_BOOT_DATA 0xf08
26
27#define HB_PWR_SUSPEND 0
28#define HB_PWR_SOFT_RESET 1
29#define HB_PWR_HARD_RESET 2
30#define HB_PWR_SHUTDOWN 3
31
32static inline void hignbank_set_pwr_suspend(void)
33{
34 writel(HB_PWR_SUSPEND, sregs_base + HB_SREG_A9_PWR_REQ);
35}
36
37static inline void hignbank_set_pwr_shutdown(void)
38{
39 writel(HB_PWR_SHUTDOWN, sregs_base + HB_SREG_A9_PWR_REQ);
40}
41
42static inline void hignbank_set_pwr_soft_reset(void)
43{
44 writel(HB_PWR_SOFT_RESET, sregs_base + HB_SREG_A9_PWR_REQ);
45}
46
47static inline void hignbank_set_pwr_hard_reset(void)
48{
49 writel(HB_PWR_HARD_RESET, sregs_base + HB_SREG_A9_PWR_REQ);
50}
51
52#endif
diff --git a/arch/arm/mach-highbank/system.c b/arch/arm/mach-highbank/system.c
new file mode 100644
index 000000000000..53f0c4c5ef1c
--- /dev/null
+++ b/arch/arm/mach-highbank/system.c
@@ -0,0 +1,33 @@
1/*
2 * Copyright 2011 Calxeda, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include <linux/io.h>
17#include <asm/smp_scu.h>
18#include <asm/proc-fns.h>
19
20#include "core.h"
21#include "sysregs.h"
22
23void arch_reset(char mode, const char *cmd)
24{
25 if (mode == 'h')
26 hignbank_set_pwr_hard_reset();
27 else
28 hignbank_set_pwr_soft_reset();
29
30 scu_power_mode(scu_base_addr, SCU_PM_POWEROFF);
31 cpu_do_idle();
32}
33
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index e605900ffe1d..5f7f9c2a34ae 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -1,5 +1,15 @@
1config IMX_HAVE_DMA_V1 1config IMX_HAVE_DMA_V1
2 bool 2 bool
3
4config HAVE_IMX_GPC
5 bool
6
7config HAVE_IMX_MMDC
8 bool
9
10config HAVE_IMX_SRC
11 bool
12
3# 13#
4# ARCH_MX31 and ARCH_MX35 are left for compatibility 14# ARCH_MX31 and ARCH_MX35 are left for compatibility
5# Some usages assume that having one of them implies not having (e.g.) ARCH_MX2. 15# Some usages assume that having one of them implies not having (e.g.) ARCH_MX2.
@@ -64,6 +74,7 @@ config SOC_IMX31
64 select ARCH_MXC_AUDMUX_V2 74 select ARCH_MXC_AUDMUX_V2
65 select ARCH_MX31 75 select ARCH_MX31
66 select MXC_AVIC 76 select MXC_AVIC
77 select SMP_ON_UP if SMP
67 78
68config SOC_IMX35 79config SOC_IMX35
69 bool 80 bool
@@ -73,6 +84,7 @@ config SOC_IMX35
73 select HAVE_EPIT 84 select HAVE_EPIT
74 select ARCH_MX35 85 select ARCH_MX35
75 select MXC_AVIC 86 select MXC_AVIC
87 select SMP_ON_UP if SMP
76 88
77 89
78if ARCH_IMX_V4_V5 90if ARCH_IMX_V4_V5
@@ -341,7 +353,7 @@ config MACH_IMX27IPCAM
341 353
342endif 354endif
343 355
344if ARCH_MX3 356if ARCH_IMX_V6_V7
345 357
346comment "MX31 platforms:" 358comment "MX31 platforms:"
347 359
@@ -592,4 +604,20 @@ config MACH_VPR200
592 Include support for VPR200 platform. This includes specific 604 Include support for VPR200 platform. This includes specific
593 configurations for the board and its peripherals. 605 configurations for the board and its peripherals.
594 606
607comment "i.MX6 family:"
608
609config SOC_IMX6Q
610 bool "i.MX6 Quad support"
611 select ARM_GIC
612 select CACHE_L2X0
613 select CPU_V7
614 select HAVE_ARM_SCU
615 select HAVE_IMX_GPC
616 select HAVE_IMX_MMDC
617 select HAVE_IMX_SRC
618 select USE_OF
619
620 help
621 This enables support for Freescale i.MX6 Quad processor.
622
595endif 623endif
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 116d4b2d2817..aba73214c2a8 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -60,3 +60,14 @@ obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o
60obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o 60obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o
61obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o 61obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
62obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o 62obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
63
64obj-$(CONFIG_DEBUG_LL) += lluart.o
65obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
66obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
67obj-$(CONFIG_HAVE_IMX_SRC) += src.o
68obj-$(CONFIG_CPU_V7) += head-v7.o
69AFLAGS_head-v7.o :=-Wa,-march=armv7-a
70obj-$(CONFIG_SMP) += platsmp.o
71obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
72obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
73obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o pm-imx6q.o
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
index dbe61201bcd8..22d85889f622 100644
--- a/arch/arm/mach-imx/Makefile.boot
+++ b/arch/arm/mach-imx/Makefile.boot
@@ -17,3 +17,7 @@ initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000
17zreladdr-$(CONFIG_ARCH_MX3) += 0x80008000 17zreladdr-$(CONFIG_ARCH_MX3) += 0x80008000
18params_phys-$(CONFIG_ARCH_MX3) := 0x80000100 18params_phys-$(CONFIG_ARCH_MX3) := 0x80000100
19initrd_phys-$(CONFIG_ARCH_MX3) := 0x80800000 19initrd_phys-$(CONFIG_ARCH_MX3) := 0x80800000
20
21zreladdr-$(CONFIG_SOC_IMX6Q) += 0x10008000
22params_phys-$(CONFIG_SOC_IMX6Q) := 0x10000100
23initrd_phys-$(CONFIG_SOC_IMX6Q) := 0x10800000
diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c
new file mode 100644
index 000000000000..e0b926dfeced
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx6q.c
@@ -0,0 +1,2012 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/init.h>
14#include <linux/types.h>
15#include <linux/clk.h>
16#include <linux/clkdev.h>
17#include <linux/io.h>
18#include <linux/of.h>
19#include <linux/of_address.h>
20#include <linux/of_irq.h>
21#include <asm/div64.h>
22#include <asm/mach/map.h>
23#include <mach/clock.h>
24#include <mach/common.h>
25#include <mach/hardware.h>
26
27#define PLL_BASE IMX_IO_ADDRESS(MX6Q_ANATOP_BASE_ADDR)
28#define PLL1_SYS (PLL_BASE + 0x000)
29#define PLL2_BUS (PLL_BASE + 0x030)
30#define PLL3_USB_OTG (PLL_BASE + 0x010)
31#define PLL4_AUDIO (PLL_BASE + 0x070)
32#define PLL5_VIDEO (PLL_BASE + 0x0a0)
33#define PLL6_MLB (PLL_BASE + 0x0d0)
34#define PLL7_USB_HOST (PLL_BASE + 0x020)
35#define PLL8_ENET (PLL_BASE + 0x0e0)
36#define PFD_480 (PLL_BASE + 0x0f0)
37#define PFD_528 (PLL_BASE + 0x100)
38#define PLL_NUM_OFFSET 0x010
39#define PLL_DENOM_OFFSET 0x020
40
41#define PFD0 7
42#define PFD1 15
43#define PFD2 23
44#define PFD3 31
45#define PFD_FRAC_MASK 0x3f
46
47#define BM_PLL_BYPASS (0x1 << 16)
48#define BM_PLL_ENABLE (0x1 << 13)
49#define BM_PLL_POWER_DOWN (0x1 << 12)
50#define BM_PLL_LOCK (0x1 << 31)
51#define BP_PLL_SYS_DIV_SELECT 0
52#define BM_PLL_SYS_DIV_SELECT (0x7f << 0)
53#define BP_PLL_BUS_DIV_SELECT 0
54#define BM_PLL_BUS_DIV_SELECT (0x1 << 0)
55#define BP_PLL_USB_DIV_SELECT 0
56#define BM_PLL_USB_DIV_SELECT (0x3 << 0)
57#define BP_PLL_AV_DIV_SELECT 0
58#define BM_PLL_AV_DIV_SELECT (0x7f << 0)
59#define BP_PLL_ENET_DIV_SELECT 0
60#define BM_PLL_ENET_DIV_SELECT (0x3 << 0)
61#define BM_PLL_ENET_EN_PCIE (0x1 << 19)
62#define BM_PLL_ENET_EN_SATA (0x1 << 20)
63
64#define CCM_BASE IMX_IO_ADDRESS(MX6Q_CCM_BASE_ADDR)
65#define CCR (CCM_BASE + 0x00)
66#define CCDR (CCM_BASE + 0x04)
67#define CSR (CCM_BASE + 0x08)
68#define CCSR (CCM_BASE + 0x0c)
69#define CACRR (CCM_BASE + 0x10)
70#define CBCDR (CCM_BASE + 0x14)
71#define CBCMR (CCM_BASE + 0x18)
72#define CSCMR1 (CCM_BASE + 0x1c)
73#define CSCMR2 (CCM_BASE + 0x20)
74#define CSCDR1 (CCM_BASE + 0x24)
75#define CS1CDR (CCM_BASE + 0x28)
76#define CS2CDR (CCM_BASE + 0x2c)
77#define CDCDR (CCM_BASE + 0x30)
78#define CHSCCDR (CCM_BASE + 0x34)
79#define CSCDR2 (CCM_BASE + 0x38)
80#define CSCDR3 (CCM_BASE + 0x3c)
81#define CSCDR4 (CCM_BASE + 0x40)
82#define CWDR (CCM_BASE + 0x44)
83#define CDHIPR (CCM_BASE + 0x48)
84#define CDCR (CCM_BASE + 0x4c)
85#define CTOR (CCM_BASE + 0x50)
86#define CLPCR (CCM_BASE + 0x54)
87#define CISR (CCM_BASE + 0x58)
88#define CIMR (CCM_BASE + 0x5c)
89#define CCOSR (CCM_BASE + 0x60)
90#define CGPR (CCM_BASE + 0x64)
91#define CCGR0 (CCM_BASE + 0x68)
92#define CCGR1 (CCM_BASE + 0x6c)
93#define CCGR2 (CCM_BASE + 0x70)
94#define CCGR3 (CCM_BASE + 0x74)
95#define CCGR4 (CCM_BASE + 0x78)
96#define CCGR5 (CCM_BASE + 0x7c)
97#define CCGR6 (CCM_BASE + 0x80)
98#define CCGR7 (CCM_BASE + 0x84)
99#define CMEOR (CCM_BASE + 0x88)
100
101#define CG0 0
102#define CG1 2
103#define CG2 4
104#define CG3 6
105#define CG4 8
106#define CG5 10
107#define CG6 12
108#define CG7 14
109#define CG8 16
110#define CG9 18
111#define CG10 20
112#define CG11 22
113#define CG12 24
114#define CG13 26
115#define CG14 28
116#define CG15 30
117
118#define BM_CCSR_PLL1_SW_SEL (0x1 << 2)
119#define BM_CCSR_STEP_SEL (0x1 << 8)
120
121#define BP_CACRR_ARM_PODF 0
122#define BM_CACRR_ARM_PODF (0x7 << 0)
123
124#define BP_CBCDR_PERIPH2_CLK2_PODF 0
125#define BM_CBCDR_PERIPH2_CLK2_PODF (0x7 << 0)
126#define BP_CBCDR_MMDC_CH1_AXI_PODF 3
127#define BM_CBCDR_MMDC_CH1_AXI_PODF (0x7 << 3)
128#define BP_CBCDR_AXI_SEL 6
129#define BM_CBCDR_AXI_SEL (0x3 << 6)
130#define BP_CBCDR_IPG_PODF 8
131#define BM_CBCDR_IPG_PODF (0x3 << 8)
132#define BP_CBCDR_AHB_PODF 10
133#define BM_CBCDR_AHB_PODF (0x7 << 10)
134#define BP_CBCDR_AXI_PODF 16
135#define BM_CBCDR_AXI_PODF (0x7 << 16)
136#define BP_CBCDR_MMDC_CH0_AXI_PODF 19
137#define BM_CBCDR_MMDC_CH0_AXI_PODF (0x7 << 19)
138#define BP_CBCDR_PERIPH_CLK_SEL 25
139#define BM_CBCDR_PERIPH_CLK_SEL (0x1 << 25)
140#define BP_CBCDR_PERIPH2_CLK_SEL 26
141#define BM_CBCDR_PERIPH2_CLK_SEL (0x1 << 26)
142#define BP_CBCDR_PERIPH_CLK2_PODF 27
143#define BM_CBCDR_PERIPH_CLK2_PODF (0x7 << 27)
144
145#define BP_CBCMR_GPU2D_AXI_SEL 0
146#define BM_CBCMR_GPU2D_AXI_SEL (0x1 << 0)
147#define BP_CBCMR_GPU3D_AXI_SEL 1
148#define BM_CBCMR_GPU3D_AXI_SEL (0x1 << 1)
149#define BP_CBCMR_GPU3D_CORE_SEL 4
150#define BM_CBCMR_GPU3D_CORE_SEL (0x3 << 4)
151#define BP_CBCMR_GPU3D_SHADER_SEL 8
152#define BM_CBCMR_GPU3D_SHADER_SEL (0x3 << 8)
153#define BP_CBCMR_PCIE_AXI_SEL 10
154#define BM_CBCMR_PCIE_AXI_SEL (0x1 << 10)
155#define BP_CBCMR_VDO_AXI_SEL 11
156#define BM_CBCMR_VDO_AXI_SEL (0x1 << 11)
157#define BP_CBCMR_PERIPH_CLK2_SEL 12
158#define BM_CBCMR_PERIPH_CLK2_SEL (0x3 << 12)
159#define BP_CBCMR_VPU_AXI_SEL 14
160#define BM_CBCMR_VPU_AXI_SEL (0x3 << 14)
161#define BP_CBCMR_GPU2D_CORE_SEL 16
162#define BM_CBCMR_GPU2D_CORE_SEL (0x3 << 16)
163#define BP_CBCMR_PRE_PERIPH_CLK_SEL 18
164#define BM_CBCMR_PRE_PERIPH_CLK_SEL (0x3 << 18)
165#define BP_CBCMR_PERIPH2_CLK2_SEL 20
166#define BM_CBCMR_PERIPH2_CLK2_SEL (0x1 << 20)
167#define BP_CBCMR_PRE_PERIPH2_CLK_SEL 21
168#define BM_CBCMR_PRE_PERIPH2_CLK_SEL (0x3 << 21)
169#define BP_CBCMR_GPU2D_CORE_PODF 23
170#define BM_CBCMR_GPU2D_CORE_PODF (0x7 << 23)
171#define BP_CBCMR_GPU3D_CORE_PODF 26
172#define BM_CBCMR_GPU3D_CORE_PODF (0x7 << 26)
173#define BP_CBCMR_GPU3D_SHADER_PODF 29
174#define BM_CBCMR_GPU3D_SHADER_PODF (0x7 << 29)
175
176#define BP_CSCMR1_PERCLK_PODF 0
177#define BM_CSCMR1_PERCLK_PODF (0x3f << 0)
178#define BP_CSCMR1_SSI1_SEL 10
179#define BM_CSCMR1_SSI1_SEL (0x3 << 10)
180#define BP_CSCMR1_SSI2_SEL 12
181#define BM_CSCMR1_SSI2_SEL (0x3 << 12)
182#define BP_CSCMR1_SSI3_SEL 14
183#define BM_CSCMR1_SSI3_SEL (0x3 << 14)
184#define BP_CSCMR1_USDHC1_SEL 16
185#define BM_CSCMR1_USDHC1_SEL (0x1 << 16)
186#define BP_CSCMR1_USDHC2_SEL 17
187#define BM_CSCMR1_USDHC2_SEL (0x1 << 17)
188#define BP_CSCMR1_USDHC3_SEL 18
189#define BM_CSCMR1_USDHC3_SEL (0x1 << 18)
190#define BP_CSCMR1_USDHC4_SEL 19
191#define BM_CSCMR1_USDHC4_SEL (0x1 << 19)
192#define BP_CSCMR1_EMI_PODF 20
193#define BM_CSCMR1_EMI_PODF (0x7 << 20)
194#define BP_CSCMR1_EMI_SLOW_PODF 23
195#define BM_CSCMR1_EMI_SLOW_PODF (0x7 << 23)
196#define BP_CSCMR1_EMI_SEL 27
197#define BM_CSCMR1_EMI_SEL (0x3 << 27)
198#define BP_CSCMR1_EMI_SLOW_SEL 29
199#define BM_CSCMR1_EMI_SLOW_SEL (0x3 << 29)
200
201#define BP_CSCMR2_CAN_PODF 2
202#define BM_CSCMR2_CAN_PODF (0x3f << 2)
203#define BM_CSCMR2_LDB_DI0_IPU_DIV (0x1 << 10)
204#define BM_CSCMR2_LDB_DI1_IPU_DIV (0x1 << 11)
205#define BP_CSCMR2_ESAI_SEL 19
206#define BM_CSCMR2_ESAI_SEL (0x3 << 19)
207
208#define BP_CSCDR1_UART_PODF 0
209#define BM_CSCDR1_UART_PODF (0x3f << 0)
210#define BP_CSCDR1_USDHC1_PODF 11
211#define BM_CSCDR1_USDHC1_PODF (0x7 << 11)
212#define BP_CSCDR1_USDHC2_PODF 16
213#define BM_CSCDR1_USDHC2_PODF (0x7 << 16)
214#define BP_CSCDR1_USDHC3_PODF 19
215#define BM_CSCDR1_USDHC3_PODF (0x7 << 19)
216#define BP_CSCDR1_USDHC4_PODF 22
217#define BM_CSCDR1_USDHC4_PODF (0x7 << 22)
218#define BP_CSCDR1_VPU_AXI_PODF 25
219#define BM_CSCDR1_VPU_AXI_PODF (0x7 << 25)
220
221#define BP_CS1CDR_SSI1_PODF 0
222#define BM_CS1CDR_SSI1_PODF (0x3f << 0)
223#define BP_CS1CDR_SSI1_PRED 6
224#define BM_CS1CDR_SSI1_PRED (0x7 << 6)
225#define BP_CS1CDR_ESAI_PRED 9
226#define BM_CS1CDR_ESAI_PRED (0x7 << 9)
227#define BP_CS1CDR_SSI3_PODF 16
228#define BM_CS1CDR_SSI3_PODF (0x3f << 16)
229#define BP_CS1CDR_SSI3_PRED 22
230#define BM_CS1CDR_SSI3_PRED (0x7 << 22)
231#define BP_CS1CDR_ESAI_PODF 25
232#define BM_CS1CDR_ESAI_PODF (0x7 << 25)
233
234#define BP_CS2CDR_SSI2_PODF 0
235#define BM_CS2CDR_SSI2_PODF (0x3f << 0)
236#define BP_CS2CDR_SSI2_PRED 6
237#define BM_CS2CDR_SSI2_PRED (0x7 << 6)
238#define BP_CS2CDR_LDB_DI0_SEL 9
239#define BM_CS2CDR_LDB_DI0_SEL (0x7 << 9)
240#define BP_CS2CDR_LDB_DI1_SEL 12
241#define BM_CS2CDR_LDB_DI1_SEL (0x7 << 12)
242#define BP_CS2CDR_ENFC_SEL 16
243#define BM_CS2CDR_ENFC_SEL (0x3 << 16)
244#define BP_CS2CDR_ENFC_PRED 18
245#define BM_CS2CDR_ENFC_PRED (0x7 << 18)
246#define BP_CS2CDR_ENFC_PODF 21
247#define BM_CS2CDR_ENFC_PODF (0x3f << 21)
248
249#define BP_CDCDR_ASRC_SERIAL_SEL 7
250#define BM_CDCDR_ASRC_SERIAL_SEL (0x3 << 7)
251#define BP_CDCDR_ASRC_SERIAL_PODF 9
252#define BM_CDCDR_ASRC_SERIAL_PODF (0x7 << 9)
253#define BP_CDCDR_ASRC_SERIAL_PRED 12
254#define BM_CDCDR_ASRC_SERIAL_PRED (0x7 << 12)
255#define BP_CDCDR_SPDIF_SEL 20
256#define BM_CDCDR_SPDIF_SEL (0x3 << 20)
257#define BP_CDCDR_SPDIF_PODF 22
258#define BM_CDCDR_SPDIF_PODF (0x7 << 22)
259#define BP_CDCDR_SPDIF_PRED 25
260#define BM_CDCDR_SPDIF_PRED (0x7 << 25)
261#define BP_CDCDR_HSI_TX_PODF 29
262#define BM_CDCDR_HSI_TX_PODF (0x7 << 29)
263#define BP_CDCDR_HSI_TX_SEL 28
264#define BM_CDCDR_HSI_TX_SEL (0x1 << 28)
265
266#define BP_CHSCCDR_IPU1_DI0_SEL 0
267#define BM_CHSCCDR_IPU1_DI0_SEL (0x7 << 0)
268#define BP_CHSCCDR_IPU1_DI0_PRE_PODF 3
269#define BM_CHSCCDR_IPU1_DI0_PRE_PODF (0x7 << 3)
270#define BP_CHSCCDR_IPU1_DI0_PRE_SEL 6
271#define BM_CHSCCDR_IPU1_DI0_PRE_SEL (0x7 << 6)
272#define BP_CHSCCDR_IPU1_DI1_SEL 9
273#define BM_CHSCCDR_IPU1_DI1_SEL (0x7 << 9)
274#define BP_CHSCCDR_IPU1_DI1_PRE_PODF 12
275#define BM_CHSCCDR_IPU1_DI1_PRE_PODF (0x7 << 12)
276#define BP_CHSCCDR_IPU1_DI1_PRE_SEL 15
277#define BM_CHSCCDR_IPU1_DI1_PRE_SEL (0x7 << 15)
278
279#define BP_CSCDR2_IPU2_DI0_SEL 0
280#define BM_CSCDR2_IPU2_DI0_SEL (0x7)
281#define BP_CSCDR2_IPU2_DI0_PRE_PODF 3
282#define BM_CSCDR2_IPU2_DI0_PRE_PODF (0x7 << 3)
283#define BP_CSCDR2_IPU2_DI0_PRE_SEL 6
284#define BM_CSCDR2_IPU2_DI0_PRE_SEL (0x7 << 6)
285#define BP_CSCDR2_IPU2_DI1_SEL 9
286#define BM_CSCDR2_IPU2_DI1_SEL (0x7 << 9)
287#define BP_CSCDR2_IPU2_DI1_PRE_PODF 12
288#define BM_CSCDR2_IPU2_DI1_PRE_PODF (0x7 << 12)
289#define BP_CSCDR2_IPU2_DI1_PRE_SEL 15
290#define BM_CSCDR2_IPU2_DI1_PRE_SEL (0x7 << 15)
291#define BP_CSCDR2_ECSPI_CLK_PODF 19
292#define BM_CSCDR2_ECSPI_CLK_PODF (0x3f << 19)
293
294#define BP_CSCDR3_IPU1_HSP_SEL 9
295#define BM_CSCDR3_IPU1_HSP_SEL (0x3 << 9)
296#define BP_CSCDR3_IPU1_HSP_PODF 11
297#define BM_CSCDR3_IPU1_HSP_PODF (0x7 << 11)
298#define BP_CSCDR3_IPU2_HSP_SEL 14
299#define BM_CSCDR3_IPU2_HSP_SEL (0x3 << 14)
300#define BP_CSCDR3_IPU2_HSP_PODF 16
301#define BM_CSCDR3_IPU2_HSP_PODF (0x7 << 16)
302
303#define BM_CDHIPR_AXI_PODF_BUSY (0x1 << 0)
304#define BM_CDHIPR_AHB_PODF_BUSY (0x1 << 1)
305#define BM_CDHIPR_MMDC_CH1_PODF_BUSY (0x1 << 2)
306#define BM_CDHIPR_PERIPH2_SEL_BUSY (0x1 << 3)
307#define BM_CDHIPR_MMDC_CH0_PODF_BUSY (0x1 << 4)
308#define BM_CDHIPR_PERIPH_SEL_BUSY (0x1 << 5)
309#define BM_CDHIPR_ARM_PODF_BUSY (0x1 << 16)
310
311#define BP_CLPCR_LPM 0
312#define BM_CLPCR_LPM (0x3 << 0)
313#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
314#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
315#define BM_CLPCR_SBYOS (0x1 << 6)
316#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
317#define BM_CLPCR_VSTBY (0x1 << 8)
318#define BP_CLPCR_STBY_COUNT 9
319#define BM_CLPCR_STBY_COUNT (0x3 << 9)
320#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
321#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
322#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
323#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
324#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
325#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
326#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
327#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
328#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
329#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
330#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
331
332#define FREQ_480M 480000000
333#define FREQ_528M 528000000
334#define FREQ_594M 594000000
335#define FREQ_650M 650000000
336#define FREQ_1300M 1300000000
337
338static struct clk pll1_sys;
339static struct clk pll2_bus;
340static struct clk pll3_usb_otg;
341static struct clk pll4_audio;
342static struct clk pll5_video;
343static struct clk pll6_mlb;
344static struct clk pll7_usb_host;
345static struct clk pll8_enet;
346static struct clk apbh_dma_clk;
347static struct clk arm_clk;
348static struct clk ipg_clk;
349static struct clk ahb_clk;
350static struct clk axi_clk;
351static struct clk mmdc_ch0_axi_clk;
352static struct clk mmdc_ch1_axi_clk;
353static struct clk periph_clk;
354static struct clk periph_pre_clk;
355static struct clk periph_clk2_clk;
356static struct clk periph2_clk;
357static struct clk periph2_pre_clk;
358static struct clk periph2_clk2_clk;
359static struct clk gpu2d_core_clk;
360static struct clk gpu3d_core_clk;
361static struct clk gpu3d_shader_clk;
362static struct clk ipg_perclk;
363static struct clk emi_clk;
364static struct clk emi_slow_clk;
365static struct clk can1_clk;
366static struct clk uart_clk;
367static struct clk usdhc1_clk;
368static struct clk usdhc2_clk;
369static struct clk usdhc3_clk;
370static struct clk usdhc4_clk;
371static struct clk vpu_clk;
372static struct clk hsi_tx_clk;
373static struct clk ipu1_di0_pre_clk;
374static struct clk ipu1_di1_pre_clk;
375static struct clk ipu2_di0_pre_clk;
376static struct clk ipu2_di1_pre_clk;
377static struct clk ipu1_clk;
378static struct clk ipu2_clk;
379static struct clk ssi1_clk;
380static struct clk ssi3_clk;
381static struct clk esai_clk;
382static struct clk ssi2_clk;
383static struct clk spdif_clk;
384static struct clk asrc_serial_clk;
385static struct clk gpu2d_axi_clk;
386static struct clk gpu3d_axi_clk;
387static struct clk pcie_clk;
388static struct clk vdo_axi_clk;
389static struct clk ldb_di0_clk;
390static struct clk ldb_di1_clk;
391static struct clk ipu1_di0_clk;
392static struct clk ipu1_di1_clk;
393static struct clk ipu2_di0_clk;
394static struct clk ipu2_di1_clk;
395static struct clk enfc_clk;
396static struct clk dummy_clk = {};
397
398static unsigned long external_high_reference;
399static unsigned long external_low_reference;
400static unsigned long oscillator_reference;
401
402static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
403{
404 return oscillator_reference;
405}
406
407static unsigned long get_high_reference_clock_rate(struct clk *clk)
408{
409 return external_high_reference;
410}
411
412static unsigned long get_low_reference_clock_rate(struct clk *clk)
413{
414 return external_low_reference;
415}
416
417static struct clk ckil_clk = {
418 .get_rate = get_low_reference_clock_rate,
419};
420
421static struct clk ckih_clk = {
422 .get_rate = get_high_reference_clock_rate,
423};
424
425static struct clk osc_clk = {
426 .get_rate = get_oscillator_reference_clock_rate,
427};
428
429static inline void __iomem *pll_get_reg_addr(struct clk *pll)
430{
431 if (pll == &pll1_sys)
432 return PLL1_SYS;
433 else if (pll == &pll2_bus)
434 return PLL2_BUS;
435 else if (pll == &pll3_usb_otg)
436 return PLL3_USB_OTG;
437 else if (pll == &pll4_audio)
438 return PLL4_AUDIO;
439 else if (pll == &pll5_video)
440 return PLL5_VIDEO;
441 else if (pll == &pll6_mlb)
442 return PLL6_MLB;
443 else if (pll == &pll7_usb_host)
444 return PLL7_USB_HOST;
445 else if (pll == &pll8_enet)
446 return PLL8_ENET;
447 else
448 BUG();
449
450 return NULL;
451}
452
453static int pll_enable(struct clk *clk)
454{
455 int timeout = 0x100000;
456 void __iomem *reg;
457 u32 val;
458
459 reg = pll_get_reg_addr(clk);
460 val = readl_relaxed(reg);
461 val &= ~BM_PLL_BYPASS;
462 val &= ~BM_PLL_POWER_DOWN;
463 /* 480MHz PLLs have the opposite definition for power bit */
464 if (clk == &pll3_usb_otg || clk == &pll7_usb_host)
465 val |= BM_PLL_POWER_DOWN;
466 writel_relaxed(val, reg);
467
468 /* Wait for PLL to lock */
469 while (!(readl_relaxed(reg) & BM_PLL_LOCK) && --timeout)
470 cpu_relax();
471
472 if (unlikely(!timeout))
473 return -EBUSY;
474
475 /* Enable the PLL output now */
476 val = readl_relaxed(reg);
477 val |= BM_PLL_ENABLE;
478 writel_relaxed(val, reg);
479
480 return 0;
481}
482
483static void pll_disable(struct clk *clk)
484{
485 void __iomem *reg;
486 u32 val;
487
488 reg = pll_get_reg_addr(clk);
489 val = readl_relaxed(reg);
490 val &= ~BM_PLL_ENABLE;
491 val |= BM_PLL_BYPASS;
492 val |= BM_PLL_POWER_DOWN;
493 if (clk == &pll3_usb_otg || clk == &pll7_usb_host)
494 val &= ~BM_PLL_POWER_DOWN;
495 writel_relaxed(val, reg);
496}
497
498static unsigned long pll1_sys_get_rate(struct clk *clk)
499{
500 u32 div = (readl_relaxed(PLL1_SYS) & BM_PLL_SYS_DIV_SELECT) >>
501 BP_PLL_SYS_DIV_SELECT;
502
503 return clk_get_rate(clk->parent) * div / 2;
504}
505
506static int pll1_sys_set_rate(struct clk *clk, unsigned long rate)
507{
508 u32 val, div;
509
510 if (rate < FREQ_650M || rate > FREQ_1300M)
511 return -EINVAL;
512
513 div = rate * 2 / clk_get_rate(clk->parent);
514 val = readl_relaxed(PLL1_SYS);
515 val &= ~BM_PLL_SYS_DIV_SELECT;
516 val |= div << BP_PLL_SYS_DIV_SELECT;
517 writel_relaxed(val, PLL1_SYS);
518
519 return 0;
520}
521
522static unsigned long pll8_enet_get_rate(struct clk *clk)
523{
524 u32 div = (readl_relaxed(PLL8_ENET) & BM_PLL_ENET_DIV_SELECT) >>
525 BP_PLL_ENET_DIV_SELECT;
526
527 switch (div) {
528 case 0:
529 return 25000000;
530 case 1:
531 return 50000000;
532 case 2:
533 return 100000000;
534 case 3:
535 return 125000000;
536 }
537
538 return 0;
539}
540
541static int pll8_enet_set_rate(struct clk *clk, unsigned long rate)
542{
543 u32 val, div;
544
545 switch (rate) {
546 case 25000000:
547 div = 0;
548 break;
549 case 50000000:
550 div = 1;
551 break;
552 case 100000000:
553 div = 2;
554 break;
555 case 125000000:
556 div = 3;
557 break;
558 default:
559 return -EINVAL;
560 }
561
562 val = readl_relaxed(PLL8_ENET);
563 val &= ~BM_PLL_ENET_DIV_SELECT;
564 val |= div << BP_PLL_ENET_DIV_SELECT;
565 writel_relaxed(val, PLL8_ENET);
566
567 return 0;
568}
569
570static unsigned long pll_av_get_rate(struct clk *clk)
571{
572 void __iomem *reg = (clk == &pll4_audio) ? PLL4_AUDIO : PLL5_VIDEO;
573 unsigned long parent_rate = clk_get_rate(clk->parent);
574 u32 mfn = readl_relaxed(reg + PLL_NUM_OFFSET);
575 u32 mfd = readl_relaxed(reg + PLL_DENOM_OFFSET);
576 u32 div = (readl_relaxed(reg) & BM_PLL_AV_DIV_SELECT) >>
577 BP_PLL_AV_DIV_SELECT;
578
579 return (parent_rate * div) + ((parent_rate / mfd) * mfn);
580}
581
582static int pll_av_set_rate(struct clk *clk, unsigned long rate)
583{
584 void __iomem *reg = (clk == &pll4_audio) ? PLL4_AUDIO : PLL5_VIDEO;
585 unsigned int parent_rate = clk_get_rate(clk->parent);
586 u32 val, div;
587 u32 mfn, mfd = 1000000;
588 s64 temp64;
589
590 if (rate < FREQ_650M || rate > FREQ_1300M)
591 return -EINVAL;
592
593 div = rate / parent_rate;
594 temp64 = (u64) (rate - div * parent_rate);
595 temp64 *= mfd;
596 do_div(temp64, parent_rate);
597 mfn = temp64;
598
599 val = readl_relaxed(reg);
600 val &= ~BM_PLL_AV_DIV_SELECT;
601 val |= div << BP_PLL_AV_DIV_SELECT;
602 writel_relaxed(val, reg);
603 writel_relaxed(mfn, reg + PLL_NUM_OFFSET);
604 writel_relaxed(mfd, reg + PLL_DENOM_OFFSET);
605
606 return 0;
607}
608
609static void __iomem *pll_get_div_reg_bit(struct clk *clk, u32 *bp, u32 *bm)
610{
611 void __iomem *reg;
612
613 if (clk == &pll2_bus) {
614 reg = PLL2_BUS;
615 *bp = BP_PLL_BUS_DIV_SELECT;
616 *bm = BM_PLL_BUS_DIV_SELECT;
617 } else if (clk == &pll3_usb_otg) {
618 reg = PLL3_USB_OTG;
619 *bp = BP_PLL_USB_DIV_SELECT;
620 *bm = BM_PLL_USB_DIV_SELECT;
621 } else if (clk == &pll7_usb_host) {
622 reg = PLL7_USB_HOST;
623 *bp = BP_PLL_USB_DIV_SELECT;
624 *bm = BM_PLL_USB_DIV_SELECT;
625 } else {
626 BUG();
627 }
628
629 return reg;
630}
631
632static unsigned long pll_get_rate(struct clk *clk)
633{
634 void __iomem *reg;
635 u32 div, bp, bm;
636
637 reg = pll_get_div_reg_bit(clk, &bp, &bm);
638 div = (readl_relaxed(reg) & bm) >> bp;
639
640 return (div == 1) ? clk_get_rate(clk->parent) * 22 :
641 clk_get_rate(clk->parent) * 20;
642}
643
644static int pll_set_rate(struct clk *clk, unsigned long rate)
645{
646 void __iomem *reg;
647 u32 val, div, bp, bm;
648
649 if (rate == FREQ_528M)
650 div = 1;
651 else if (rate == FREQ_480M)
652 div = 0;
653 else
654 return -EINVAL;
655
656 reg = pll_get_div_reg_bit(clk, &bp, &bm);
657 val = readl_relaxed(reg);
658 val &= ~bm;
659 val |= div << bp;
660 writel_relaxed(val, reg);
661
662 return 0;
663}
664
665#define pll2_bus_get_rate pll_get_rate
666#define pll2_bus_set_rate pll_set_rate
667#define pll3_usb_otg_get_rate pll_get_rate
668#define pll3_usb_otg_set_rate pll_set_rate
669#define pll7_usb_host_get_rate pll_get_rate
670#define pll7_usb_host_set_rate pll_set_rate
671#define pll4_audio_get_rate pll_av_get_rate
672#define pll4_audio_set_rate pll_av_set_rate
673#define pll5_video_get_rate pll_av_get_rate
674#define pll5_video_set_rate pll_av_set_rate
675#define pll6_mlb_get_rate NULL
676#define pll6_mlb_set_rate NULL
677
678#define DEF_PLL(name) \
679 static struct clk name = { \
680 .enable = pll_enable, \
681 .disable = pll_disable, \
682 .get_rate = name##_get_rate, \
683 .set_rate = name##_set_rate, \
684 .parent = &osc_clk, \
685 }
686
687DEF_PLL(pll1_sys);
688DEF_PLL(pll2_bus);
689DEF_PLL(pll3_usb_otg);
690DEF_PLL(pll4_audio);
691DEF_PLL(pll5_video);
692DEF_PLL(pll6_mlb);
693DEF_PLL(pll7_usb_host);
694DEF_PLL(pll8_enet);
695
696static unsigned long pfd_get_rate(struct clk *clk)
697{
698 u64 tmp = (u64) clk_get_rate(clk->parent) * 18;
699 u32 frac, bp_frac;
700
701 if (apbh_dma_clk.usecount == 0)
702 apbh_dma_clk.enable(&apbh_dma_clk);
703
704 bp_frac = clk->enable_shift - 7;
705 frac = readl_relaxed(clk->enable_reg) >> bp_frac & PFD_FRAC_MASK;
706 do_div(tmp, frac);
707
708 return tmp;
709}
710
711static int pfd_set_rate(struct clk *clk, unsigned long rate)
712{
713 u32 val, frac, bp_frac;
714 u64 tmp = (u64) clk_get_rate(clk->parent) * 18;
715
716 if (apbh_dma_clk.usecount == 0)
717 apbh_dma_clk.enable(&apbh_dma_clk);
718
719 /*
720 * Round up the divider so that we don't set a rate
721 * higher than what is requested
722 */
723 tmp += rate / 2;
724 do_div(tmp, rate);
725 frac = tmp;
726 frac = (frac < 12) ? 12 : frac;
727 frac = (frac > 35) ? 35 : frac;
728
729 /*
730 * The frac field always starts from 7 bits lower
731 * position of enable bit
732 */
733 bp_frac = clk->enable_shift - 7;
734 val = readl_relaxed(clk->enable_reg);
735 val &= ~(PFD_FRAC_MASK << bp_frac);
736 val |= frac << bp_frac;
737 writel_relaxed(val, clk->enable_reg);
738
739 tmp = (u64) clk_get_rate(clk->parent) * 18;
740 do_div(tmp, frac);
741
742 if (apbh_dma_clk.usecount == 0)
743 apbh_dma_clk.disable(&apbh_dma_clk);
744
745 return 0;
746}
747
748static unsigned long pfd_round_rate(struct clk *clk, unsigned long rate)
749{
750 u32 frac;
751 u64 tmp;
752
753 tmp = (u64) clk_get_rate(clk->parent) * 18;
754 tmp += rate / 2;
755 do_div(tmp, rate);
756 frac = tmp;
757 frac = (frac < 12) ? 12 : frac;
758 frac = (frac > 35) ? 35 : frac;
759 tmp = (u64) clk_get_rate(clk->parent) * 18;
760 do_div(tmp, frac);
761
762 return tmp;
763}
764
765static int pfd_enable(struct clk *clk)
766{
767 u32 val;
768
769 if (apbh_dma_clk.usecount == 0)
770 apbh_dma_clk.enable(&apbh_dma_clk);
771
772 val = readl_relaxed(clk->enable_reg);
773 val &= ~(1 << clk->enable_shift);
774 writel_relaxed(val, clk->enable_reg);
775
776 if (apbh_dma_clk.usecount == 0)
777 apbh_dma_clk.disable(&apbh_dma_clk);
778
779 return 0;
780}
781
782static void pfd_disable(struct clk *clk)
783{
784 u32 val;
785
786 if (apbh_dma_clk.usecount == 0)
787 apbh_dma_clk.enable(&apbh_dma_clk);
788
789 val = readl_relaxed(clk->enable_reg);
790 val |= 1 << clk->enable_shift;
791 writel_relaxed(val, clk->enable_reg);
792
793 if (apbh_dma_clk.usecount == 0)
794 apbh_dma_clk.disable(&apbh_dma_clk);
795}
796
797#define DEF_PFD(name, er, es, p) \
798 static struct clk name = { \
799 .enable_reg = er, \
800 .enable_shift = es, \
801 .enable = pfd_enable, \
802 .disable = pfd_disable, \
803 .get_rate = pfd_get_rate, \
804 .set_rate = pfd_set_rate, \
805 .round_rate = pfd_round_rate, \
806 .parent = p, \
807 }
808
809DEF_PFD(pll2_pfd_352m, PFD_528, PFD0, &pll2_bus);
810DEF_PFD(pll2_pfd_594m, PFD_528, PFD1, &pll2_bus);
811DEF_PFD(pll2_pfd_400m, PFD_528, PFD2, &pll2_bus);
812DEF_PFD(pll3_pfd_720m, PFD_480, PFD0, &pll3_usb_otg);
813DEF_PFD(pll3_pfd_540m, PFD_480, PFD1, &pll3_usb_otg);
814DEF_PFD(pll3_pfd_508m, PFD_480, PFD2, &pll3_usb_otg);
815DEF_PFD(pll3_pfd_454m, PFD_480, PFD3, &pll3_usb_otg);
816
817static unsigned long pll2_200m_get_rate(struct clk *clk)
818{
819 return clk_get_rate(clk->parent) / 2;
820}
821
822static struct clk pll2_200m = {
823 .parent = &pll2_pfd_400m,
824 .get_rate = pll2_200m_get_rate,
825};
826
827static unsigned long pll3_120m_get_rate(struct clk *clk)
828{
829 return clk_get_rate(clk->parent) / 4;
830}
831
832static struct clk pll3_120m = {
833 .parent = &pll3_usb_otg,
834 .get_rate = pll3_120m_get_rate,
835};
836
837static unsigned long pll3_80m_get_rate(struct clk *clk)
838{
839 return clk_get_rate(clk->parent) / 6;
840}
841
842static struct clk pll3_80m = {
843 .parent = &pll3_usb_otg,
844 .get_rate = pll3_80m_get_rate,
845};
846
847static unsigned long pll3_60m_get_rate(struct clk *clk)
848{
849 return clk_get_rate(clk->parent) / 8;
850}
851
852static struct clk pll3_60m = {
853 .parent = &pll3_usb_otg,
854 .get_rate = pll3_60m_get_rate,
855};
856
857static int pll1_sw_clk_set_parent(struct clk *clk, struct clk *parent)
858{
859 u32 val = readl_relaxed(CCSR);
860
861 if (parent == &pll1_sys) {
862 val &= ~BM_CCSR_PLL1_SW_SEL;
863 val &= ~BM_CCSR_STEP_SEL;
864 } else if (parent == &osc_clk) {
865 val |= BM_CCSR_PLL1_SW_SEL;
866 val &= ~BM_CCSR_STEP_SEL;
867 } else if (parent == &pll2_pfd_400m) {
868 val |= BM_CCSR_PLL1_SW_SEL;
869 val |= BM_CCSR_STEP_SEL;
870 } else {
871 return -EINVAL;
872 }
873
874 writel_relaxed(val, CCSR);
875
876 return 0;
877}
878
879static struct clk pll1_sw_clk = {
880 .parent = &pll1_sys,
881 .set_parent = pll1_sw_clk_set_parent,
882};
883
884static void calc_pred_podf_dividers(u32 div, u32 *pred, u32 *podf)
885{
886 u32 min_pred, temp_pred, old_err, err;
887
888 if (div >= 512) {
889 *pred = 8;
890 *podf = 64;
891 } else if (div >= 8) {
892 min_pred = (div - 1) / 64 + 1;
893 old_err = 8;
894 for (temp_pred = 8; temp_pred >= min_pred; temp_pred--) {
895 err = div % temp_pred;
896 if (err == 0) {
897 *pred = temp_pred;
898 break;
899 }
900 err = temp_pred - err;
901 if (err < old_err) {
902 old_err = err;
903 *pred = temp_pred;
904 }
905 }
906 *podf = (div + *pred - 1) / *pred;
907 } else if (div < 8) {
908 *pred = div;
909 *podf = 1;
910 }
911}
912
913static int _clk_enable(struct clk *clk)
914{
915 u32 reg;
916 reg = readl_relaxed(clk->enable_reg);
917 reg |= 0x3 << clk->enable_shift;
918 writel_relaxed(reg, clk->enable_reg);
919
920 return 0;
921}
922
923static void _clk_disable(struct clk *clk)
924{
925 u32 reg;
926 reg = readl_relaxed(clk->enable_reg);
927 reg &= ~(0x3 << clk->enable_shift);
928 writel_relaxed(reg, clk->enable_reg);
929}
930
931struct divider {
932 struct clk *clk;
933 void __iomem *reg;
934 u32 bp_pred;
935 u32 bm_pred;
936 u32 bp_podf;
937 u32 bm_podf;
938};
939
940#define DEF_CLK_DIV1(d, c, r, b) \
941 static struct divider d = { \
942 .clk = c, \
943 .reg = r, \
944 .bp_podf = BP_##r##_##b##_PODF, \
945 .bm_podf = BM_##r##_##b##_PODF, \
946 }
947
948DEF_CLK_DIV1(arm_div, &arm_clk, CACRR, ARM);
949DEF_CLK_DIV1(ipg_div, &ipg_clk, CBCDR, IPG);
950DEF_CLK_DIV1(ahb_div, &ahb_clk, CBCDR, AHB);
951DEF_CLK_DIV1(axi_div, &axi_clk, CBCDR, AXI);
952DEF_CLK_DIV1(mmdc_ch0_axi_div, &mmdc_ch0_axi_clk, CBCDR, MMDC_CH0_AXI);
953DEF_CLK_DIV1(mmdc_ch1_axi_div, &mmdc_ch1_axi_clk, CBCDR, MMDC_CH1_AXI);
954DEF_CLK_DIV1(periph_clk2_div, &periph_clk2_clk, CBCDR, PERIPH_CLK2);
955DEF_CLK_DIV1(periph2_clk2_div, &periph2_clk2_clk, CBCDR, PERIPH2_CLK2);
956DEF_CLK_DIV1(gpu2d_core_div, &gpu2d_core_clk, CBCMR, GPU2D_CORE);
957DEF_CLK_DIV1(gpu3d_core_div, &gpu3d_core_clk, CBCMR, GPU3D_CORE);
958DEF_CLK_DIV1(gpu3d_shader_div, &gpu3d_shader_clk, CBCMR, GPU3D_SHADER);
959DEF_CLK_DIV1(ipg_perclk_div, &ipg_perclk, CSCMR1, PERCLK);
960DEF_CLK_DIV1(emi_div, &emi_clk, CSCMR1, EMI);
961DEF_CLK_DIV1(emi_slow_div, &emi_slow_clk, CSCMR1, EMI_SLOW);
962DEF_CLK_DIV1(can_div, &can1_clk, CSCMR2, CAN);
963DEF_CLK_DIV1(uart_div, &uart_clk, CSCDR1, UART);
964DEF_CLK_DIV1(usdhc1_div, &usdhc1_clk, CSCDR1, USDHC1);
965DEF_CLK_DIV1(usdhc2_div, &usdhc2_clk, CSCDR1, USDHC2);
966DEF_CLK_DIV1(usdhc3_div, &usdhc3_clk, CSCDR1, USDHC3);
967DEF_CLK_DIV1(usdhc4_div, &usdhc4_clk, CSCDR1, USDHC4);
968DEF_CLK_DIV1(vpu_div, &vpu_clk, CSCDR1, VPU_AXI);
969DEF_CLK_DIV1(hsi_tx_div, &hsi_tx_clk, CDCDR, HSI_TX);
970DEF_CLK_DIV1(ipu1_di0_pre_div, &ipu1_di0_pre_clk, CHSCCDR, IPU1_DI0_PRE);
971DEF_CLK_DIV1(ipu1_di1_pre_div, &ipu1_di1_pre_clk, CHSCCDR, IPU1_DI1_PRE);
972DEF_CLK_DIV1(ipu2_di0_pre_div, &ipu2_di0_pre_clk, CSCDR2, IPU2_DI0_PRE);
973DEF_CLK_DIV1(ipu2_di1_pre_div, &ipu2_di1_pre_clk, CSCDR2, IPU2_DI1_PRE);
974DEF_CLK_DIV1(ipu1_div, &ipu1_clk, CSCDR3, IPU1_HSP);
975DEF_CLK_DIV1(ipu2_div, &ipu2_clk, CSCDR3, IPU2_HSP);
976
977#define DEF_CLK_DIV2(d, c, r, b) \
978 static struct divider d = { \
979 .clk = c, \
980 .reg = r, \
981 .bp_pred = BP_##r##_##b##_PRED, \
982 .bm_pred = BM_##r##_##b##_PRED, \
983 .bp_podf = BP_##r##_##b##_PODF, \
984 .bm_podf = BM_##r##_##b##_PODF, \
985 }
986
987DEF_CLK_DIV2(ssi1_div, &ssi1_clk, CS1CDR, SSI1);
988DEF_CLK_DIV2(ssi3_div, &ssi3_clk, CS1CDR, SSI3);
989DEF_CLK_DIV2(esai_div, &esai_clk, CS1CDR, ESAI);
990DEF_CLK_DIV2(ssi2_div, &ssi2_clk, CS2CDR, SSI2);
991DEF_CLK_DIV2(enfc_div, &enfc_clk, CS2CDR, ENFC);
992DEF_CLK_DIV2(spdif_div, &spdif_clk, CDCDR, SPDIF);
993DEF_CLK_DIV2(asrc_serial_div, &asrc_serial_clk, CDCDR, ASRC_SERIAL);
994
995static struct divider *dividers[] = {
996 &arm_div,
997 &ipg_div,
998 &ahb_div,
999 &axi_div,
1000 &mmdc_ch0_axi_div,
1001 &mmdc_ch1_axi_div,
1002 &periph_clk2_div,
1003 &periph2_clk2_div,
1004 &gpu2d_core_div,
1005 &gpu3d_core_div,
1006 &gpu3d_shader_div,
1007 &ipg_perclk_div,
1008 &emi_div,
1009 &emi_slow_div,
1010 &can_div,
1011 &uart_div,
1012 &usdhc1_div,
1013 &usdhc2_div,
1014 &usdhc3_div,
1015 &usdhc4_div,
1016 &vpu_div,
1017 &hsi_tx_div,
1018 &ipu1_di0_pre_div,
1019 &ipu1_di1_pre_div,
1020 &ipu2_di0_pre_div,
1021 &ipu2_di1_pre_div,
1022 &ipu1_div,
1023 &ipu2_div,
1024 &ssi1_div,
1025 &ssi3_div,
1026 &esai_div,
1027 &ssi2_div,
1028 &enfc_div,
1029 &spdif_div,
1030 &asrc_serial_div,
1031};
1032
1033static unsigned long ldb_di_clk_get_rate(struct clk *clk)
1034{
1035 u32 val = readl_relaxed(CSCMR2);
1036
1037 val &= (clk == &ldb_di0_clk) ? BM_CSCMR2_LDB_DI0_IPU_DIV :
1038 BM_CSCMR2_LDB_DI1_IPU_DIV;
1039 if (val)
1040 return clk_get_rate(clk->parent) / 7;
1041 else
1042 return clk_get_rate(clk->parent) * 2 / 7;
1043}
1044
1045static int ldb_di_clk_set_rate(struct clk *clk, unsigned long rate)
1046{
1047 unsigned long parent_rate = clk_get_rate(clk->parent);
1048 u32 val = readl_relaxed(CSCMR2);
1049
1050 if (rate * 7 <= parent_rate + parent_rate / 20)
1051 val |= BM_CSCMR2_LDB_DI0_IPU_DIV;
1052 else
1053 val &= ~BM_CSCMR2_LDB_DI0_IPU_DIV;
1054
1055 writel_relaxed(val, CSCMR2);
1056
1057 return 0;
1058}
1059
1060static unsigned long ldb_di_clk_round_rate(struct clk *clk, unsigned long rate)
1061{
1062 unsigned long parent_rate = clk_get_rate(clk->parent);
1063
1064 if (rate * 7 <= parent_rate + parent_rate / 20)
1065 return parent_rate / 7;
1066 else
1067 return 2 * parent_rate / 7;
1068}
1069
1070static unsigned long _clk_get_rate(struct clk *clk)
1071{
1072 struct divider *d;
1073 u32 val, pred, podf;
1074 int i, num;
1075
1076 if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
1077 return ldb_di_clk_get_rate(clk);
1078
1079 num = ARRAY_SIZE(dividers);
1080 for (i = 0; i < num; i++)
1081 if (dividers[i]->clk == clk) {
1082 d = dividers[i];
1083 break;
1084 }
1085 if (i == num)
1086 return clk_get_rate(clk->parent);
1087
1088 val = readl_relaxed(d->reg);
1089 pred = ((val & d->bm_pred) >> d->bp_pred) + 1;
1090 podf = ((val & d->bm_podf) >> d->bp_podf) + 1;
1091
1092 return clk_get_rate(clk->parent) / (pred * podf);
1093}
1094
1095static int clk_busy_wait(struct clk *clk)
1096{
1097 int timeout = 0x100000;
1098 u32 bm;
1099
1100 if (clk == &axi_clk)
1101 bm = BM_CDHIPR_AXI_PODF_BUSY;
1102 else if (clk == &ahb_clk)
1103 bm = BM_CDHIPR_AHB_PODF_BUSY;
1104 else if (clk == &mmdc_ch0_axi_clk)
1105 bm = BM_CDHIPR_MMDC_CH0_PODF_BUSY;
1106 else if (clk == &periph_clk)
1107 bm = BM_CDHIPR_PERIPH_SEL_BUSY;
1108 else if (clk == &arm_clk)
1109 bm = BM_CDHIPR_ARM_PODF_BUSY;
1110 else
1111 return -EINVAL;
1112
1113 while ((readl_relaxed(CDHIPR) & bm) && --timeout)
1114 cpu_relax();
1115
1116 if (unlikely(!timeout))
1117 return -EBUSY;
1118
1119 return 0;
1120}
1121
1122static int _clk_set_rate(struct clk *clk, unsigned long rate)
1123{
1124 unsigned long parent_rate = clk_get_rate(clk->parent);
1125 struct divider *d;
1126 u32 val, div, max_div, pred = 0, podf;
1127 int i, num;
1128
1129 if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
1130 return ldb_di_clk_set_rate(clk, rate);
1131
1132 num = ARRAY_SIZE(dividers);
1133 for (i = 0; i < num; i++)
1134 if (dividers[i]->clk == clk) {
1135 d = dividers[i];
1136 break;
1137 }
1138 if (i == num)
1139 return -EINVAL;
1140
1141 max_div = ((d->bm_pred >> d->bp_pred) + 1) *
1142 ((d->bm_pred >> d->bp_pred) + 1);
1143
1144 div = parent_rate / rate;
1145 if (div == 0)
1146 div++;
1147
1148 if ((parent_rate / div != rate) || div > max_div)
1149 return -EINVAL;
1150
1151 if (d->bm_pred) {
1152 calc_pred_podf_dividers(div, &pred, &podf);
1153 } else {
1154 pred = 1;
1155 podf = div;
1156 }
1157
1158 val = readl_relaxed(d->reg);
1159 val &= ~(d->bm_pred | d->bm_podf);
1160 val |= (pred - 1) << d->bp_pred | (podf - 1) << d->bp_podf;
1161 writel_relaxed(val, d->reg);
1162
1163 if (clk == &axi_clk || clk == &ahb_clk ||
1164 clk == &mmdc_ch0_axi_clk || clk == &arm_clk)
1165 return clk_busy_wait(clk);
1166
1167 return 0;
1168}
1169
1170static unsigned long _clk_round_rate(struct clk *clk, unsigned long rate)
1171{
1172 unsigned long parent_rate = clk_get_rate(clk->parent);
1173 u32 div = parent_rate / rate;
1174 u32 div_max, pred = 0, podf;
1175 struct divider *d;
1176 int i, num;
1177
1178 if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
1179 return ldb_di_clk_round_rate(clk, rate);
1180
1181 num = ARRAY_SIZE(dividers);
1182 for (i = 0; i < num; i++)
1183 if (dividers[i]->clk == clk) {
1184 d = dividers[i];
1185 break;
1186 }
1187 if (i == num)
1188 return -EINVAL;
1189
1190 if (div == 0 || parent_rate % rate)
1191 div++;
1192
1193 if (d->bm_pred) {
1194 calc_pred_podf_dividers(div, &pred, &podf);
1195 div = pred * podf;
1196 } else {
1197 div_max = (d->bm_podf >> d->bp_podf) + 1;
1198 if (div > div_max)
1199 div = div_max;
1200 }
1201
1202 return parent_rate / div;
1203}
1204
1205struct multiplexer {
1206 struct clk *clk;
1207 void __iomem *reg;
1208 u32 bp;
1209 u32 bm;
1210 int pnum;
1211 struct clk *parents[];
1212};
1213
1214static struct multiplexer axi_mux = {
1215 .clk = &axi_clk,
1216 .reg = CBCDR,
1217 .bp = BP_CBCDR_AXI_SEL,
1218 .bm = BM_CBCDR_AXI_SEL,
1219 .parents = {
1220 &periph_clk,
1221 &pll2_pfd_400m,
1222 &pll3_pfd_540m,
1223 NULL
1224 },
1225};
1226
1227static struct multiplexer periph_mux = {
1228 .clk = &periph_clk,
1229 .reg = CBCDR,
1230 .bp = BP_CBCDR_PERIPH_CLK_SEL,
1231 .bm = BM_CBCDR_PERIPH_CLK_SEL,
1232 .parents = {
1233 &periph_pre_clk,
1234 &periph_clk2_clk,
1235 NULL
1236 },
1237};
1238
1239static struct multiplexer periph_pre_mux = {
1240 .clk = &periph_pre_clk,
1241 .reg = CBCMR,
1242 .bp = BP_CBCMR_PRE_PERIPH_CLK_SEL,
1243 .bm = BM_CBCMR_PRE_PERIPH_CLK_SEL,
1244 .parents = {
1245 &pll2_bus,
1246 &pll2_pfd_400m,
1247 &pll2_pfd_352m,
1248 &pll2_200m,
1249 NULL
1250 },
1251};
1252
1253static struct multiplexer periph_clk2_mux = {
1254 .clk = &periph_clk2_clk,
1255 .reg = CBCMR,
1256 .bp = BP_CBCMR_PERIPH_CLK2_SEL,
1257 .bm = BM_CBCMR_PERIPH_CLK2_SEL,
1258 .parents = {
1259 &pll3_usb_otg,
1260 &osc_clk,
1261 NULL
1262 },
1263};
1264
1265static struct multiplexer periph2_mux = {
1266 .clk = &periph2_clk,
1267 .reg = CBCDR,
1268 .bp = BP_CBCDR_PERIPH2_CLK_SEL,
1269 .bm = BM_CBCDR_PERIPH2_CLK_SEL,
1270 .parents = {
1271 &periph2_pre_clk,
1272 &periph2_clk2_clk,
1273 NULL
1274 },
1275};
1276
1277static struct multiplexer periph2_pre_mux = {
1278 .clk = &periph2_pre_clk,
1279 .reg = CBCMR,
1280 .bp = BP_CBCMR_PRE_PERIPH2_CLK_SEL,
1281 .bm = BM_CBCMR_PRE_PERIPH2_CLK_SEL,
1282 .parents = {
1283 &pll2_bus,
1284 &pll2_pfd_400m,
1285 &pll2_pfd_352m,
1286 &pll2_200m,
1287 NULL
1288 },
1289};
1290
1291static struct multiplexer periph2_clk2_mux = {
1292 .clk = &periph2_clk2_clk,
1293 .reg = CBCMR,
1294 .bp = BP_CBCMR_PERIPH2_CLK2_SEL,
1295 .bm = BM_CBCMR_PERIPH2_CLK2_SEL,
1296 .parents = {
1297 &pll3_usb_otg,
1298 &osc_clk,
1299 NULL
1300 },
1301};
1302
1303static struct multiplexer gpu2d_axi_mux = {
1304 .clk = &gpu2d_axi_clk,
1305 .reg = CBCMR,
1306 .bp = BP_CBCMR_GPU2D_AXI_SEL,
1307 .bm = BM_CBCMR_GPU2D_AXI_SEL,
1308 .parents = {
1309 &axi_clk,
1310 &ahb_clk,
1311 NULL
1312 },
1313};
1314
1315static struct multiplexer gpu3d_axi_mux = {
1316 .clk = &gpu3d_axi_clk,
1317 .reg = CBCMR,
1318 .bp = BP_CBCMR_GPU3D_AXI_SEL,
1319 .bm = BM_CBCMR_GPU3D_AXI_SEL,
1320 .parents = {
1321 &axi_clk,
1322 &ahb_clk,
1323 NULL
1324 },
1325};
1326
1327static struct multiplexer gpu3d_core_mux = {
1328 .clk = &gpu3d_core_clk,
1329 .reg = CBCMR,
1330 .bp = BP_CBCMR_GPU3D_CORE_SEL,
1331 .bm = BM_CBCMR_GPU3D_CORE_SEL,
1332 .parents = {
1333 &mmdc_ch0_axi_clk,
1334 &pll3_usb_otg,
1335 &pll2_pfd_594m,
1336 &pll2_pfd_400m,
1337 NULL
1338 },
1339};
1340
1341static struct multiplexer gpu3d_shader_mux = {
1342 .clk = &gpu3d_shader_clk,
1343 .reg = CBCMR,
1344 .bp = BP_CBCMR_GPU3D_SHADER_SEL,
1345 .bm = BM_CBCMR_GPU3D_SHADER_SEL,
1346 .parents = {
1347 &mmdc_ch0_axi_clk,
1348 &pll3_usb_otg,
1349 &pll2_pfd_594m,
1350 &pll3_pfd_720m,
1351 NULL
1352 },
1353};
1354
1355static struct multiplexer pcie_axi_mux = {
1356 .clk = &pcie_clk,
1357 .reg = CBCMR,
1358 .bp = BP_CBCMR_PCIE_AXI_SEL,
1359 .bm = BM_CBCMR_PCIE_AXI_SEL,
1360 .parents = {
1361 &axi_clk,
1362 &ahb_clk,
1363 NULL
1364 },
1365};
1366
1367static struct multiplexer vdo_axi_mux = {
1368 .clk = &vdo_axi_clk,
1369 .reg = CBCMR,
1370 .bp = BP_CBCMR_VDO_AXI_SEL,
1371 .bm = BM_CBCMR_VDO_AXI_SEL,
1372 .parents = {
1373 &axi_clk,
1374 &ahb_clk,
1375 NULL
1376 },
1377};
1378
1379static struct multiplexer vpu_axi_mux = {
1380 .clk = &vpu_clk,
1381 .reg = CBCMR,
1382 .bp = BP_CBCMR_VPU_AXI_SEL,
1383 .bm = BM_CBCMR_VPU_AXI_SEL,
1384 .parents = {
1385 &axi_clk,
1386 &pll2_pfd_400m,
1387 &pll2_pfd_352m,
1388 NULL
1389 },
1390};
1391
1392static struct multiplexer gpu2d_core_mux = {
1393 .clk = &gpu2d_core_clk,
1394 .reg = CBCMR,
1395 .bp = BP_CBCMR_GPU2D_CORE_SEL,
1396 .bm = BM_CBCMR_GPU2D_CORE_SEL,
1397 .parents = {
1398 &axi_clk,
1399 &pll3_usb_otg,
1400 &pll2_pfd_352m,
1401 &pll2_pfd_400m,
1402 NULL
1403 },
1404};
1405
1406#define DEF_SSI_MUX(id) \
1407 static struct multiplexer ssi##id##_mux = { \
1408 .clk = &ssi##id##_clk, \
1409 .reg = CSCMR1, \
1410 .bp = BP_CSCMR1_SSI##id##_SEL, \
1411 .bm = BM_CSCMR1_SSI##id##_SEL, \
1412 .parents = { \
1413 &pll3_pfd_508m, \
1414 &pll3_pfd_454m, \
1415 &pll4_audio, \
1416 NULL \
1417 }, \
1418 }
1419
1420DEF_SSI_MUX(1);
1421DEF_SSI_MUX(2);
1422DEF_SSI_MUX(3);
1423
1424#define DEF_USDHC_MUX(id) \
1425 static struct multiplexer usdhc##id##_mux = { \
1426 .clk = &usdhc##id##_clk, \
1427 .reg = CSCMR1, \
1428 .bp = BP_CSCMR1_USDHC##id##_SEL, \
1429 .bm = BM_CSCMR1_USDHC##id##_SEL, \
1430 .parents = { \
1431 &pll2_pfd_400m, \
1432 &pll2_pfd_352m, \
1433 NULL \
1434 }, \
1435 }
1436
1437DEF_USDHC_MUX(1);
1438DEF_USDHC_MUX(2);
1439DEF_USDHC_MUX(3);
1440DEF_USDHC_MUX(4);
1441
1442static struct multiplexer emi_mux = {
1443 .clk = &emi_clk,
1444 .reg = CSCMR1,
1445 .bp = BP_CSCMR1_EMI_SEL,
1446 .bm = BM_CSCMR1_EMI_SEL,
1447 .parents = {
1448 &axi_clk,
1449 &pll3_usb_otg,
1450 &pll2_pfd_400m,
1451 &pll2_pfd_352m,
1452 NULL
1453 },
1454};
1455
1456static struct multiplexer emi_slow_mux = {
1457 .clk = &emi_slow_clk,
1458 .reg = CSCMR1,
1459 .bp = BP_CSCMR1_EMI_SLOW_SEL,
1460 .bm = BM_CSCMR1_EMI_SLOW_SEL,
1461 .parents = {
1462 &axi_clk,
1463 &pll3_usb_otg,
1464 &pll2_pfd_400m,
1465 &pll2_pfd_352m,
1466 NULL
1467 },
1468};
1469
1470static struct multiplexer esai_mux = {
1471 .clk = &esai_clk,
1472 .reg = CSCMR2,
1473 .bp = BP_CSCMR2_ESAI_SEL,
1474 .bm = BM_CSCMR2_ESAI_SEL,
1475 .parents = {
1476 &pll4_audio,
1477 &pll3_pfd_508m,
1478 &pll3_pfd_454m,
1479 &pll3_usb_otg,
1480 NULL
1481 },
1482};
1483
1484#define DEF_LDB_DI_MUX(id) \
1485 static struct multiplexer ldb_di##id##_mux = { \
1486 .clk = &ldb_di##id##_clk, \
1487 .reg = CS2CDR, \
1488 .bp = BP_CS2CDR_LDB_DI##id##_SEL, \
1489 .bm = BM_CS2CDR_LDB_DI##id##_SEL, \
1490 .parents = { \
1491 &pll5_video, \
1492 &pll2_pfd_352m, \
1493 &pll2_pfd_400m, \
1494 &pll3_pfd_540m, \
1495 &pll3_usb_otg, \
1496 NULL \
1497 }, \
1498 }
1499
1500DEF_LDB_DI_MUX(0);
1501DEF_LDB_DI_MUX(1);
1502
1503static struct multiplexer enfc_mux = {
1504 .clk = &enfc_clk,
1505 .reg = CS2CDR,
1506 .bp = BP_CS2CDR_ENFC_SEL,
1507 .bm = BM_CS2CDR_ENFC_SEL,
1508 .parents = {
1509 &pll2_pfd_352m,
1510 &pll2_bus,
1511 &pll3_usb_otg,
1512 &pll2_pfd_400m,
1513 NULL
1514 },
1515};
1516
1517static struct multiplexer spdif_mux = {
1518 .clk = &spdif_clk,
1519 .reg = CDCDR,
1520 .bp = BP_CDCDR_SPDIF_SEL,
1521 .bm = BM_CDCDR_SPDIF_SEL,
1522 .parents = {
1523 &pll4_audio,
1524 &pll3_pfd_508m,
1525 &pll3_pfd_454m,
1526 &pll3_usb_otg,
1527 NULL
1528 },
1529};
1530
1531static struct multiplexer asrc_serial_mux = {
1532 .clk = &asrc_serial_clk,
1533 .reg = CDCDR,
1534 .bp = BP_CDCDR_ASRC_SERIAL_SEL,
1535 .bm = BM_CDCDR_ASRC_SERIAL_SEL,
1536 .parents = {
1537 &pll4_audio,
1538 &pll3_pfd_508m,
1539 &pll3_pfd_454m,
1540 &pll3_usb_otg,
1541 NULL
1542 },
1543};
1544
1545static struct multiplexer hsi_tx_mux = {
1546 .clk = &hsi_tx_clk,
1547 .reg = CDCDR,
1548 .bp = BP_CDCDR_HSI_TX_SEL,
1549 .bm = BM_CDCDR_HSI_TX_SEL,
1550 .parents = {
1551 &pll3_120m,
1552 &pll2_pfd_400m,
1553 NULL
1554 },
1555};
1556
1557#define DEF_IPU_DI_PRE_MUX(r, i, d) \
1558 static struct multiplexer ipu##i##_di##d##_pre_mux = { \
1559 .clk = &ipu##i##_di##d##_pre_clk, \
1560 .reg = r, \
1561 .bp = BP_##r##_IPU##i##_DI##d##_PRE_SEL, \
1562 .bm = BM_##r##_IPU##i##_DI##d##_PRE_SEL, \
1563 .parents = { \
1564 &mmdc_ch0_axi_clk, \
1565 &pll3_usb_otg, \
1566 &pll5_video, \
1567 &pll2_pfd_352m, \
1568 &pll2_pfd_400m, \
1569 &pll3_pfd_540m, \
1570 NULL \
1571 }, \
1572 }
1573
1574DEF_IPU_DI_PRE_MUX(CHSCCDR, 1, 0);
1575DEF_IPU_DI_PRE_MUX(CHSCCDR, 1, 1);
1576DEF_IPU_DI_PRE_MUX(CSCDR2, 2, 0);
1577DEF_IPU_DI_PRE_MUX(CSCDR2, 2, 1);
1578
1579#define DEF_IPU_DI_MUX(r, i, d) \
1580 static struct multiplexer ipu##i##_di##d##_mux = { \
1581 .clk = &ipu##i##_di##d##_clk, \
1582 .reg = r, \
1583 .bp = BP_##r##_IPU##i##_DI##d##_SEL, \
1584 .bm = BM_##r##_IPU##i##_DI##d##_SEL, \
1585 .parents = { \
1586 &ipu##i##_di##d##_pre_clk, \
1587 &dummy_clk, \
1588 &dummy_clk, \
1589 &ldb_di0_clk, \
1590 &ldb_di1_clk, \
1591 NULL \
1592 }, \
1593 }
1594
1595DEF_IPU_DI_MUX(CHSCCDR, 1, 0);
1596DEF_IPU_DI_MUX(CHSCCDR, 1, 1);
1597DEF_IPU_DI_MUX(CSCDR2, 2, 0);
1598DEF_IPU_DI_MUX(CSCDR2, 2, 1);
1599
1600#define DEF_IPU_MUX(id) \
1601 static struct multiplexer ipu##id##_mux = { \
1602 .clk = &ipu##id##_clk, \
1603 .reg = CSCDR3, \
1604 .bp = BP_CSCDR3_IPU##id##_HSP_SEL, \
1605 .bm = BM_CSCDR3_IPU##id##_HSP_SEL, \
1606 .parents = { \
1607 &mmdc_ch0_axi_clk, \
1608 &pll2_pfd_400m, \
1609 &pll3_120m, \
1610 &pll3_pfd_540m, \
1611 NULL \
1612 }, \
1613 }
1614
1615DEF_IPU_MUX(1);
1616DEF_IPU_MUX(2);
1617
1618static struct multiplexer *multiplexers[] = {
1619 &axi_mux,
1620 &periph_mux,
1621 &periph_pre_mux,
1622 &periph_clk2_mux,
1623 &periph2_mux,
1624 &periph2_pre_mux,
1625 &periph2_clk2_mux,
1626 &gpu2d_axi_mux,
1627 &gpu3d_axi_mux,
1628 &gpu3d_core_mux,
1629 &gpu3d_shader_mux,
1630 &pcie_axi_mux,
1631 &vdo_axi_mux,
1632 &vpu_axi_mux,
1633 &gpu2d_core_mux,
1634 &ssi1_mux,
1635 &ssi2_mux,
1636 &ssi3_mux,
1637 &usdhc1_mux,
1638 &usdhc2_mux,
1639 &usdhc3_mux,
1640 &usdhc4_mux,
1641 &emi_mux,
1642 &emi_slow_mux,
1643 &esai_mux,
1644 &ldb_di0_mux,
1645 &ldb_di1_mux,
1646 &enfc_mux,
1647 &spdif_mux,
1648 &asrc_serial_mux,
1649 &hsi_tx_mux,
1650 &ipu1_di0_pre_mux,
1651 &ipu1_di0_mux,
1652 &ipu1_di1_pre_mux,
1653 &ipu1_di1_mux,
1654 &ipu2_di0_pre_mux,
1655 &ipu2_di0_mux,
1656 &ipu2_di1_pre_mux,
1657 &ipu2_di1_mux,
1658 &ipu1_mux,
1659 &ipu2_mux,
1660};
1661
1662static int _clk_set_parent(struct clk *clk, struct clk *parent)
1663{
1664 struct multiplexer *m;
1665 int i, num;
1666 u32 val;
1667
1668 num = ARRAY_SIZE(multiplexers);
1669 for (i = 0; i < num; i++)
1670 if (multiplexers[i]->clk == clk) {
1671 m = multiplexers[i];
1672 break;
1673 }
1674 if (i == num)
1675 return -EINVAL;
1676
1677 i = 0;
1678 while (m->parents[i]) {
1679 if (parent == m->parents[i])
1680 break;
1681 i++;
1682 }
1683 if (!m->parents[i])
1684 return -EINVAL;
1685
1686 val = readl_relaxed(m->reg);
1687 val &= ~m->bm;
1688 val |= i << m->bp;
1689 writel_relaxed(val, m->reg);
1690
1691 if (clk == &periph_clk)
1692 return clk_busy_wait(clk);
1693
1694 return 0;
1695}
1696
1697#define DEF_NG_CLK(name, p) \
1698 static struct clk name = { \
1699 .get_rate = _clk_get_rate, \
1700 .set_rate = _clk_set_rate, \
1701 .round_rate = _clk_round_rate, \
1702 .set_parent = _clk_set_parent, \
1703 .parent = p, \
1704 }
1705
1706DEF_NG_CLK(periph_clk2_clk, &osc_clk);
1707DEF_NG_CLK(periph_pre_clk, &pll2_bus);
1708DEF_NG_CLK(periph_clk, &periph_pre_clk);
1709DEF_NG_CLK(periph2_clk2_clk, &osc_clk);
1710DEF_NG_CLK(periph2_pre_clk, &pll2_bus);
1711DEF_NG_CLK(periph2_clk, &periph2_pre_clk);
1712DEF_NG_CLK(axi_clk, &periph_clk);
1713DEF_NG_CLK(emi_clk, &axi_clk);
1714DEF_NG_CLK(arm_clk, &pll1_sw_clk);
1715DEF_NG_CLK(ahb_clk, &periph_clk);
1716DEF_NG_CLK(ipg_clk, &ahb_clk);
1717DEF_NG_CLK(ipg_perclk, &ipg_clk);
1718DEF_NG_CLK(ipu1_di0_pre_clk, &pll3_pfd_540m);
1719DEF_NG_CLK(ipu1_di1_pre_clk, &pll3_pfd_540m);
1720DEF_NG_CLK(ipu2_di0_pre_clk, &pll3_pfd_540m);
1721DEF_NG_CLK(ipu2_di1_pre_clk, &pll3_pfd_540m);
1722DEF_NG_CLK(asrc_serial_clk, &pll3_usb_otg);
1723
1724#define DEF_CLK(name, er, es, p, s) \
1725 static struct clk name = { \
1726 .enable_reg = er, \
1727 .enable_shift = es, \
1728 .enable = _clk_enable, \
1729 .disable = _clk_disable, \
1730 .get_rate = _clk_get_rate, \
1731 .set_rate = _clk_set_rate, \
1732 .round_rate = _clk_round_rate, \
1733 .set_parent = _clk_set_parent, \
1734 .parent = p, \
1735 .secondary = s, \
1736 }
1737
1738DEF_CLK(aips_tz1_clk, CCGR0, CG0, &ahb_clk, NULL);
1739DEF_CLK(aips_tz2_clk, CCGR0, CG1, &ahb_clk, NULL);
1740DEF_CLK(apbh_dma_clk, CCGR0, CG2, &ahb_clk, NULL);
1741DEF_CLK(asrc_clk, CCGR0, CG3, &pll4_audio, NULL);
1742DEF_CLK(can1_serial_clk, CCGR0, CG8, &pll3_usb_otg, NULL);
1743DEF_CLK(can1_clk, CCGR0, CG7, &pll3_usb_otg, &can1_serial_clk);
1744DEF_CLK(can2_serial_clk, CCGR0, CG10, &pll3_usb_otg, NULL);
1745DEF_CLK(can2_clk, CCGR0, CG9, &pll3_usb_otg, &can2_serial_clk);
1746DEF_CLK(ecspi1_clk, CCGR1, CG0, &pll3_60m, NULL);
1747DEF_CLK(ecspi2_clk, CCGR1, CG1, &pll3_60m, NULL);
1748DEF_CLK(ecspi3_clk, CCGR1, CG2, &pll3_60m, NULL);
1749DEF_CLK(ecspi4_clk, CCGR1, CG3, &pll3_60m, NULL);
1750DEF_CLK(ecspi5_clk, CCGR1, CG4, &pll3_60m, NULL);
1751DEF_CLK(enet_clk, CCGR1, CG5, &ipg_clk, NULL);
1752DEF_CLK(esai_clk, CCGR1, CG8, &pll3_usb_otg, NULL);
1753DEF_CLK(gpt_serial_clk, CCGR1, CG11, &ipg_perclk, NULL);
1754DEF_CLK(gpt_clk, CCGR1, CG10, &ipg_perclk, &gpt_serial_clk);
1755DEF_CLK(gpu2d_core_clk, CCGR1, CG12, &pll2_pfd_352m, &gpu2d_axi_clk);
1756DEF_CLK(gpu3d_core_clk, CCGR1, CG13, &pll2_pfd_594m, &gpu3d_axi_clk);
1757DEF_CLK(gpu3d_shader_clk, CCGR1, CG13, &pll3_pfd_720m, &gpu3d_axi_clk);
1758DEF_CLK(hdmi_iahb_clk, CCGR2, CG0, &ahb_clk, NULL);
1759DEF_CLK(hdmi_isfr_clk, CCGR2, CG2, &pll3_pfd_540m, &hdmi_iahb_clk);
1760DEF_CLK(i2c1_clk, CCGR2, CG3, &ipg_perclk, NULL);
1761DEF_CLK(i2c2_clk, CCGR2, CG4, &ipg_perclk, NULL);
1762DEF_CLK(i2c3_clk, CCGR2, CG5, &ipg_perclk, NULL);
1763DEF_CLK(iim_clk, CCGR2, CG6, &ipg_clk, NULL);
1764DEF_CLK(enfc_clk, CCGR2, CG7, &pll2_pfd_352m, NULL);
1765DEF_CLK(ipu1_clk, CCGR3, CG0, &mmdc_ch0_axi_clk, NULL);
1766DEF_CLK(ipu1_di0_clk, CCGR3, CG1, &ipu1_di0_pre_clk, NULL);
1767DEF_CLK(ipu1_di1_clk, CCGR3, CG2, &ipu1_di1_pre_clk, NULL);
1768DEF_CLK(ipu2_clk, CCGR3, CG3, &mmdc_ch0_axi_clk, NULL);
1769DEF_CLK(ipu2_di0_clk, CCGR3, CG4, &ipu2_di0_pre_clk, NULL);
1770DEF_CLK(ipu2_di1_clk, CCGR3, CG5, &ipu2_di1_pre_clk, NULL);
1771DEF_CLK(ldb_di0_clk, CCGR3, CG6, &pll3_pfd_540m, NULL);
1772DEF_CLK(ldb_di1_clk, CCGR3, CG7, &pll3_pfd_540m, NULL);
1773DEF_CLK(hsi_tx_clk, CCGR3, CG8, &pll2_pfd_400m, NULL);
1774DEF_CLK(mlb_clk, CCGR3, CG9, &pll6_mlb, NULL);
1775DEF_CLK(mmdc_ch0_ipg_clk, CCGR3, CG12, &ipg_clk, NULL);
1776DEF_CLK(mmdc_ch0_axi_clk, CCGR3, CG10, &periph_clk, &mmdc_ch0_ipg_clk);
1777DEF_CLK(mmdc_ch1_ipg_clk, CCGR3, CG13, &ipg_clk, NULL);
1778DEF_CLK(mmdc_ch1_axi_clk, CCGR3, CG11, &periph2_clk, &mmdc_ch1_ipg_clk);
1779DEF_CLK(openvg_axi_clk, CCGR3, CG13, &axi_clk, NULL);
1780DEF_CLK(pwm1_clk, CCGR4, CG8, &ipg_perclk, NULL);
1781DEF_CLK(pwm2_clk, CCGR4, CG9, &ipg_perclk, NULL);
1782DEF_CLK(pwm3_clk, CCGR4, CG10, &ipg_perclk, NULL);
1783DEF_CLK(pwm4_clk, CCGR4, CG11, &ipg_perclk, NULL);
1784DEF_CLK(gpmi_bch_apb_clk, CCGR4, CG12, &usdhc3_clk, NULL);
1785DEF_CLK(gpmi_bch_clk, CCGR4, CG13, &usdhc4_clk, &gpmi_bch_apb_clk);
1786DEF_CLK(gpmi_apb_clk, CCGR4, CG15, &usdhc3_clk, &gpmi_bch_clk);
1787DEF_CLK(gpmi_io_clk, CCGR4, CG14, &enfc_clk, &gpmi_apb_clk);
1788DEF_CLK(sdma_clk, CCGR5, CG3, &ahb_clk, NULL);
1789DEF_CLK(spba_clk, CCGR5, CG6, &ipg_clk, NULL);
1790DEF_CLK(spdif_clk, CCGR5, CG7, &pll3_usb_otg, &spba_clk);
1791DEF_CLK(ssi1_clk, CCGR5, CG9, &pll3_pfd_508m, NULL);
1792DEF_CLK(ssi2_clk, CCGR5, CG10, &pll3_pfd_508m, NULL);
1793DEF_CLK(ssi3_clk, CCGR5, CG11, &pll3_pfd_508m, NULL);
1794DEF_CLK(uart_serial_clk, CCGR5, CG13, &pll3_usb_otg, NULL);
1795DEF_CLK(uart_clk, CCGR5, CG12, &pll3_80m, &uart_serial_clk);
1796DEF_CLK(usboh3_clk, CCGR6, CG0, &ipg_clk, NULL);
1797DEF_CLK(usdhc1_clk, CCGR6, CG1, &pll2_pfd_400m, NULL);
1798DEF_CLK(usdhc2_clk, CCGR6, CG2, &pll2_pfd_400m, NULL);
1799DEF_CLK(usdhc3_clk, CCGR6, CG3, &pll2_pfd_400m, NULL);
1800DEF_CLK(usdhc4_clk, CCGR6, CG4, &pll2_pfd_400m, NULL);
1801DEF_CLK(emi_slow_clk, CCGR6, CG5, &axi_clk, NULL);
1802DEF_CLK(vdo_axi_clk, CCGR6, CG6, &axi_clk, NULL);
1803DEF_CLK(vpu_clk, CCGR6, CG7, &axi_clk, NULL);
1804
1805static int pcie_clk_enable(struct clk *clk)
1806{
1807 u32 val;
1808
1809 val = readl_relaxed(PLL8_ENET);
1810 val |= BM_PLL_ENET_EN_PCIE;
1811 writel_relaxed(val, PLL8_ENET);
1812
1813 return _clk_enable(clk);
1814}
1815
1816static void pcie_clk_disable(struct clk *clk)
1817{
1818 u32 val;
1819
1820 _clk_disable(clk);
1821
1822 val = readl_relaxed(PLL8_ENET);
1823 val &= BM_PLL_ENET_EN_PCIE;
1824 writel_relaxed(val, PLL8_ENET);
1825}
1826
1827static struct clk pcie_clk = {
1828 .enable_reg = CCGR4,
1829 .enable_shift = CG0,
1830 .enable = pcie_clk_enable,
1831 .disable = pcie_clk_disable,
1832 .set_parent = _clk_set_parent,
1833 .parent = &axi_clk,
1834 .secondary = &pll8_enet,
1835};
1836
1837static int sata_clk_enable(struct clk *clk)
1838{
1839 u32 val;
1840
1841 val = readl_relaxed(PLL8_ENET);
1842 val |= BM_PLL_ENET_EN_SATA;
1843 writel_relaxed(val, PLL8_ENET);
1844
1845 return _clk_enable(clk);
1846}
1847
1848static void sata_clk_disable(struct clk *clk)
1849{
1850 u32 val;
1851
1852 _clk_disable(clk);
1853
1854 val = readl_relaxed(PLL8_ENET);
1855 val &= BM_PLL_ENET_EN_SATA;
1856 writel_relaxed(val, PLL8_ENET);
1857}
1858
1859static struct clk sata_clk = {
1860 .enable_reg = CCGR5,
1861 .enable_shift = CG2,
1862 .enable = sata_clk_enable,
1863 .disable = sata_clk_disable,
1864 .parent = &ipg_clk,
1865 .secondary = &pll8_enet,
1866};
1867
1868#define _REGISTER_CLOCK(d, n, c) \
1869 { \
1870 .dev_id = d, \
1871 .con_id = n, \
1872 .clk = &c, \
1873 }
1874
1875static struct clk_lookup lookups[] = {
1876 _REGISTER_CLOCK("2020000.uart", NULL, uart_clk),
1877 _REGISTER_CLOCK("21e8000.uart", NULL, uart_clk),
1878 _REGISTER_CLOCK("21ec000.uart", NULL, uart_clk),
1879 _REGISTER_CLOCK("21f0000.uart", NULL, uart_clk),
1880 _REGISTER_CLOCK("21f4000.uart", NULL, uart_clk),
1881 _REGISTER_CLOCK("2188000.enet", NULL, enet_clk),
1882 _REGISTER_CLOCK("2190000.usdhc", NULL, usdhc1_clk),
1883 _REGISTER_CLOCK("2194000.usdhc", NULL, usdhc2_clk),
1884 _REGISTER_CLOCK("2198000.usdhc", NULL, usdhc3_clk),
1885 _REGISTER_CLOCK("219c000.usdhc", NULL, usdhc4_clk),
1886 _REGISTER_CLOCK("21a0000.i2c", NULL, i2c1_clk),
1887 _REGISTER_CLOCK("21a4000.i2c", NULL, i2c2_clk),
1888 _REGISTER_CLOCK("21a8000.i2c", NULL, i2c3_clk),
1889 _REGISTER_CLOCK("2008000.ecspi", NULL, ecspi1_clk),
1890 _REGISTER_CLOCK("200c000.ecspi", NULL, ecspi2_clk),
1891 _REGISTER_CLOCK("2010000.ecspi", NULL, ecspi3_clk),
1892 _REGISTER_CLOCK("2014000.ecspi", NULL, ecspi4_clk),
1893 _REGISTER_CLOCK("2018000.ecspi", NULL, ecspi5_clk),
1894 _REGISTER_CLOCK("20ec000.sdma", NULL, sdma_clk),
1895 _REGISTER_CLOCK("20bc000.wdog", NULL, dummy_clk),
1896 _REGISTER_CLOCK("20c0000.wdog", NULL, dummy_clk),
1897 _REGISTER_CLOCK(NULL, "ckih", ckih_clk),
1898 _REGISTER_CLOCK(NULL, "ckil_clk", ckil_clk),
1899 _REGISTER_CLOCK(NULL, "aips_tz1_clk", aips_tz1_clk),
1900 _REGISTER_CLOCK(NULL, "aips_tz2_clk", aips_tz2_clk),
1901 _REGISTER_CLOCK(NULL, "asrc_clk", asrc_clk),
1902 _REGISTER_CLOCK(NULL, "can2_clk", can2_clk),
1903 _REGISTER_CLOCK(NULL, "hdmi_isfr_clk", hdmi_isfr_clk),
1904 _REGISTER_CLOCK(NULL, "iim_clk", iim_clk),
1905 _REGISTER_CLOCK(NULL, "mlb_clk", mlb_clk),
1906 _REGISTER_CLOCK(NULL, "openvg_axi_clk", openvg_axi_clk),
1907 _REGISTER_CLOCK(NULL, "pwm1_clk", pwm1_clk),
1908 _REGISTER_CLOCK(NULL, "pwm2_clk", pwm2_clk),
1909 _REGISTER_CLOCK(NULL, "pwm3_clk", pwm3_clk),
1910 _REGISTER_CLOCK(NULL, "pwm4_clk", pwm4_clk),
1911 _REGISTER_CLOCK(NULL, "gpmi_io_clk", gpmi_io_clk),
1912 _REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk),
1913 _REGISTER_CLOCK(NULL, "sata_clk", sata_clk),
1914};
1915
1916int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
1917{
1918 u32 val = readl_relaxed(CLPCR);
1919
1920 val &= ~BM_CLPCR_LPM;
1921 switch (mode) {
1922 case WAIT_CLOCKED:
1923 break;
1924 case WAIT_UNCLOCKED:
1925 val |= 0x1 << BP_CLPCR_LPM;
1926 break;
1927 case STOP_POWER_ON:
1928 val |= 0x2 << BP_CLPCR_LPM;
1929 break;
1930 case WAIT_UNCLOCKED_POWER_OFF:
1931 val |= 0x1 << BP_CLPCR_LPM;
1932 val &= ~BM_CLPCR_VSTBY;
1933 val &= ~BM_CLPCR_SBYOS;
1934 val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
1935 break;
1936 case STOP_POWER_OFF:
1937 val |= 0x2 << BP_CLPCR_LPM;
1938 val |= 0x3 << BP_CLPCR_STBY_COUNT;
1939 val |= BM_CLPCR_VSTBY;
1940 val |= BM_CLPCR_SBYOS;
1941 val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
1942 break;
1943 default:
1944 return -EINVAL;
1945 }
1946 writel_relaxed(val, CLPCR);
1947
1948 return 0;
1949}
1950
1951static struct map_desc imx6q_clock_desc[] = {
1952 imx_map_entry(MX6Q, CCM, MT_DEVICE),
1953 imx_map_entry(MX6Q, ANATOP, MT_DEVICE),
1954};
1955
1956int __init mx6q_clocks_init(void)
1957{
1958 struct device_node *np;
1959 void __iomem *base;
1960 int i, irq;
1961
1962 iotable_init(imx6q_clock_desc, ARRAY_SIZE(imx6q_clock_desc));
1963
1964 /* retrieve the freqency of fixed clocks from device tree */
1965 for_each_compatible_node(np, NULL, "fixed-clock") {
1966 u32 rate;
1967 if (of_property_read_u32(np, "clock-frequency", &rate))
1968 continue;
1969
1970 if (of_device_is_compatible(np, "fsl,imx-ckil"))
1971 external_low_reference = rate;
1972 else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
1973 external_high_reference = rate;
1974 else if (of_device_is_compatible(np, "fsl,imx-osc"))
1975 oscillator_reference = rate;
1976 }
1977
1978 for (i = 0; i < ARRAY_SIZE(lookups); i++)
1979 clkdev_add(&lookups[i]);
1980
1981 /* only keep necessary clocks on */
1982 writel_relaxed(0x3 << CG0 | 0x3 << CG1 | 0x3 << CG2, CCGR0);
1983 writel_relaxed(0x3 << CG8 | 0x3 << CG9 | 0x3 << CG10, CCGR2);
1984 writel_relaxed(0x3 << CG10 | 0x3 << CG12, CCGR3);
1985 writel_relaxed(0x3 << CG4 | 0x3 << CG6 | 0x3 << CG7, CCGR4);
1986 writel_relaxed(0x3 << CG0, CCGR5);
1987 writel_relaxed(0, CCGR6);
1988 writel_relaxed(0, CCGR7);
1989
1990 clk_enable(&uart_clk);
1991 clk_enable(&mmdc_ch0_axi_clk);
1992
1993 clk_set_rate(&pll4_audio, FREQ_650M);
1994 clk_set_rate(&pll5_video, FREQ_650M);
1995 clk_set_parent(&ipu1_di0_clk, &ipu1_di0_pre_clk);
1996 clk_set_parent(&ipu1_di0_pre_clk, &pll5_video);
1997 clk_set_parent(&gpu3d_shader_clk, &pll2_pfd_594m);
1998 clk_set_rate(&gpu3d_shader_clk, FREQ_594M);
1999 clk_set_parent(&gpu3d_core_clk, &mmdc_ch0_axi_clk);
2000 clk_set_rate(&gpu3d_core_clk, FREQ_528M);
2001 clk_set_parent(&asrc_serial_clk, &pll3_usb_otg);
2002 clk_set_rate(&asrc_serial_clk, 1500000);
2003 clk_set_rate(&enfc_clk, 11000000);
2004
2005 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
2006 base = of_iomap(np, 0);
2007 WARN_ON(!base);
2008 irq = irq_of_parse_and_map(np, 0);
2009 mxc_timer_init(&gpt_clk, base, irq);
2010
2011 return 0;
2012}
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
new file mode 100644
index 000000000000..e1537f9e45b8
--- /dev/null
+++ b/arch/arm/mach-imx/gpc.c
@@ -0,0 +1,113 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/io.h>
14#include <linux/irq.h>
15#include <linux/of.h>
16#include <linux/of_address.h>
17#include <linux/of_irq.h>
18#include <asm/hardware/gic.h>
19
20#define GPC_IMR1 0x008
21#define GPC_PGC_CPU_PDN 0x2a0
22
23#define IMR_NUM 4
24
25static void __iomem *gpc_base;
26static u32 gpc_wake_irqs[IMR_NUM];
27static u32 gpc_saved_imrs[IMR_NUM];
28
29void imx_gpc_pre_suspend(void)
30{
31 void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
32 int i;
33
34 /* Tell GPC to power off ARM core when suspend */
35 writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
36
37 for (i = 0; i < IMR_NUM; i++) {
38 gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
39 writel_relaxed(~gpc_wake_irqs[i], reg_imr1 + i * 4);
40 }
41}
42
43void imx_gpc_post_resume(void)
44{
45 void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
46 int i;
47
48 /* Keep ARM core powered on for other low-power modes */
49 writel_relaxed(0x0, gpc_base + GPC_PGC_CPU_PDN);
50
51 for (i = 0; i < IMR_NUM; i++)
52 writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
53}
54
55static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on)
56{
57 unsigned int idx = d->irq / 32 - 1;
58 u32 mask;
59
60 /* Sanity check for SPI irq */
61 if (d->irq < 32)
62 return -EINVAL;
63
64 mask = 1 << d->irq % 32;
65 gpc_wake_irqs[idx] = on ? gpc_wake_irqs[idx] | mask :
66 gpc_wake_irqs[idx] & ~mask;
67
68 return 0;
69}
70
71static void imx_gpc_irq_unmask(struct irq_data *d)
72{
73 void __iomem *reg;
74 u32 val;
75
76 /* Sanity check for SPI irq */
77 if (d->irq < 32)
78 return;
79
80 reg = gpc_base + GPC_IMR1 + (d->irq / 32 - 1) * 4;
81 val = readl_relaxed(reg);
82 val &= ~(1 << d->irq % 32);
83 writel_relaxed(val, reg);
84}
85
86static void imx_gpc_irq_mask(struct irq_data *d)
87{
88 void __iomem *reg;
89 u32 val;
90
91 /* Sanity check for SPI irq */
92 if (d->irq < 32)
93 return;
94
95 reg = gpc_base + GPC_IMR1 + (d->irq / 32 - 1) * 4;
96 val = readl_relaxed(reg);
97 val |= 1 << (d->irq % 32);
98 writel_relaxed(val, reg);
99}
100
101void __init imx_gpc_init(void)
102{
103 struct device_node *np;
104
105 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
106 gpc_base = of_iomap(np, 0);
107 WARN_ON(!gpc_base);
108
109 /* Register GPC as the secondary interrupt controller behind GIC */
110 gic_arch_extn.irq_mask = imx_gpc_irq_mask;
111 gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
112 gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake;
113}
diff --git a/arch/arm/mach-imx/head-v7.S b/arch/arm/mach-imx/head-v7.S
new file mode 100644
index 000000000000..6229efbc70cb
--- /dev/null
+++ b/arch/arm/mach-imx/head-v7.S
@@ -0,0 +1,99 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/linkage.h>
14#include <linux/init.h>
15#include <asm/asm-offsets.h>
16#include <asm/hardware/cache-l2x0.h>
17
18 .section ".text.head", "ax"
19 __CPUINIT
20
21/*
22 * The secondary kernel init calls v7_flush_dcache_all before it enables
23 * the L1; however, the L1 comes out of reset in an undefined state, so
24 * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
25 * of cache lines with uninitialized data and uninitialized tags to get
26 * written out to memory, which does really unpleasant things to the main
27 * processor. We fix this by performing an invalidate, rather than a
28 * clean + invalidate, before jumping into the kernel.
29 *
30 * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs
31 * to be called for both secondary cores startup and primary core resume
32 * procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S.
33 */
34ENTRY(v7_invalidate_l1)
35 mov r0, #0
36 mcr p15, 2, r0, c0, c0, 0
37 mrc p15, 1, r0, c0, c0, 0
38
39 ldr r1, =0x7fff
40 and r2, r1, r0, lsr #13
41
42 ldr r1, =0x3ff
43
44 and r3, r1, r0, lsr #3 @ NumWays - 1
45 add r2, r2, #1 @ NumSets
46
47 and r0, r0, #0x7
48 add r0, r0, #4 @ SetShift
49
50 clz r1, r3 @ WayShift
51 add r4, r3, #1 @ NumWays
521: sub r2, r2, #1 @ NumSets--
53 mov r3, r4 @ Temp = NumWays
542: subs r3, r3, #1 @ Temp--
55 mov r5, r3, lsl r1
56 mov r6, r2, lsl r0
57 orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
58 mcr p15, 0, r5, c7, c6, 2
59 bgt 2b
60 cmp r2, #0
61 bgt 1b
62 dsb
63 isb
64 mov pc, lr
65ENDPROC(v7_invalidate_l1)
66
67#ifdef CONFIG_SMP
68ENTRY(v7_secondary_startup)
69 bl v7_invalidate_l1
70 b secondary_startup
71ENDPROC(v7_secondary_startup)
72#endif
73
74/*
75 * The following code is located into the .data section. This is to
76 * allow phys_l2x0_saved_regs to be accessed with a relative load
77 * as we are running on physical address here.
78 */
79 .data
80 .align
81
82 .macro pl310_resume
83 ldr r2, phys_l2x0_saved_regs
84 ldr r0, [r2, #L2X0_R_PHY_BASE] @ get physical base of l2x0
85 ldr r1, [r2, #L2X0_R_AUX_CTRL] @ get aux_ctrl value
86 str r1, [r0, #L2X0_AUX_CTRL] @ restore aux_ctrl
87 mov r1, #0x1
88 str r1, [r0, #L2X0_CTRL] @ re-enable L2
89 .endm
90
91ENTRY(v7_cpu_resume)
92 bl v7_invalidate_l1
93 pl310_resume
94 b cpu_resume
95ENDPROC(v7_cpu_resume)
96
97 .globl phys_l2x0_saved_regs
98phys_l2x0_saved_regs:
99 .long 0
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c
new file mode 100644
index 000000000000..89493abd497c
--- /dev/null
+++ b/arch/arm/mach-imx/hotplug.c
@@ -0,0 +1,44 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/errno.h>
14#include <asm/cacheflush.h>
15#include <mach/common.h>
16
17int platform_cpu_kill(unsigned int cpu)
18{
19 return 1;
20}
21
22/*
23 * platform-specific code to shutdown a CPU
24 *
25 * Called with IRQs disabled
26 */
27void platform_cpu_die(unsigned int cpu)
28{
29 flush_cache_all();
30 imx_enable_cpu(cpu, false);
31 cpu_do_idle();
32
33 /* We should never return from idle */
34 panic("cpu %d unexpectedly exit from shutdown\n", cpu);
35}
36
37int platform_cpu_disable(unsigned int cpu)
38{
39 /*
40 * we don't allow CPU 0 to be shutdown (it is still too special
41 * e.g. clock tick interrupts)
42 */
43 return cpu == 0 ? -EPERM : 0;
44}
diff --git a/arch/arm/mach-imx/lluart.c b/arch/arm/mach-imx/lluart.c
new file mode 100644
index 000000000000..d4ab6f29a766
--- /dev/null
+++ b/arch/arm/mach-imx/lluart.c
@@ -0,0 +1,32 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/init.h>
14#include <asm/page.h>
15#include <asm/sizes.h>
16#include <asm/mach/map.h>
17#include <mach/hardware.h>
18
19static struct map_desc imx_lluart_desc = {
20#ifdef CONFIG_DEBUG_IMX6Q_UART
21 .virtual = MX6Q_IO_P2V(MX6Q_UART4_BASE_ADDR),
22 .pfn = __phys_to_pfn(MX6Q_UART4_BASE_ADDR),
23 .length = MX6Q_UART4_SIZE,
24 .type = MT_DEVICE,
25#endif
26};
27
28void __init imx_lluart_map_io(void)
29{
30 if (imx_lluart_desc.virtual)
31 iotable_init(&imx_lluart_desc, 1);
32}
diff --git a/arch/arm/mach-imx/localtimer.c b/arch/arm/mach-imx/localtimer.c
new file mode 100644
index 000000000000..3a163515d41f
--- /dev/null
+++ b/arch/arm/mach-imx/localtimer.c
@@ -0,0 +1,35 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/init.h>
14#include <linux/clockchips.h>
15#include <linux/of_address.h>
16#include <linux/of_irq.h>
17#include <asm/smp_twd.h>
18
19/*
20 * Setup the local clock events for a CPU.
21 */
22int __cpuinit local_timer_setup(struct clock_event_device *evt)
23{
24 struct device_node *np;
25
26 np = of_find_compatible_node(NULL, NULL, "arm,smp-twd");
27 if (!twd_base) {
28 twd_base = of_iomap(np, 0);
29 WARN_ON(!twd_base);
30 }
31 evt->irq = irq_of_parse_and_map(np, 0);
32 twd_timer_setup(evt);
33
34 return 0;
35}
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
new file mode 100644
index 000000000000..8bf5fa349484
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -0,0 +1,84 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/init.h>
14#include <linux/irq.h>
15#include <linux/irqdomain.h>
16#include <linux/of.h>
17#include <linux/of_irq.h>
18#include <linux/of_platform.h>
19#include <asm/hardware/cache-l2x0.h>
20#include <asm/hardware/gic.h>
21#include <asm/mach/arch.h>
22#include <asm/mach/time.h>
23#include <mach/common.h>
24#include <mach/hardware.h>
25
26static void __init imx6q_init_machine(void)
27{
28 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
29
30 imx6q_pm_init();
31}
32
33static void __init imx6q_map_io(void)
34{
35 imx_lluart_map_io();
36 imx_scu_map_io();
37}
38
39static void __init imx6q_gpio_add_irq_domain(struct device_node *np,
40 struct device_node *interrupt_parent)
41{
42 static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS -
43 32 * 7; /* imx6q gets 7 gpio ports */
44
45 irq_domain_add_simple(np, gpio_irq_base);
46 gpio_irq_base += 32;
47}
48
49static const struct of_device_id imx6q_irq_match[] __initconst = {
50 { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
51 { .compatible = "fsl,imx6q-gpio", .data = imx6q_gpio_add_irq_domain, },
52 { /* sentinel */ }
53};
54
55static void __init imx6q_init_irq(void)
56{
57 l2x0_of_init(0, ~0UL);
58 imx_src_init();
59 imx_gpc_init();
60 of_irq_init(imx6q_irq_match);
61}
62
63static void __init imx6q_timer_init(void)
64{
65 mx6q_clocks_init();
66}
67
68static struct sys_timer imx6q_timer = {
69 .init = imx6q_timer_init,
70};
71
72static const char *imx6q_dt_compat[] __initdata = {
73 "fsl,imx6q-sabreauto",
74 NULL,
75};
76
77DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)")
78 .map_io = imx6q_map_io,
79 .init_irq = imx6q_init_irq,
80 .handle_irq = imx6q_handle_irq,
81 .timer = &imx6q_timer,
82 .init_machine = imx6q_init_machine,
83 .dt_compat = imx6q_dt_compat,
84MACHINE_END
diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
new file mode 100644
index 000000000000..c461e98496c3
--- /dev/null
+++ b/arch/arm/mach-imx/mmdc.c
@@ -0,0 +1,72 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_address.h>
18#include <linux/of_device.h>
19
20#define MMDC_MAPSR 0x404
21#define BP_MMDC_MAPSR_PSD 0
22#define BP_MMDC_MAPSR_PSS 4
23
24static int __devinit imx_mmdc_probe(struct platform_device *pdev)
25{
26 struct device_node *np = pdev->dev.of_node;
27 void __iomem *mmdc_base, *reg;
28 u32 val;
29 int timeout = 0x400;
30
31 mmdc_base = of_iomap(np, 0);
32 WARN_ON(!mmdc_base);
33
34 reg = mmdc_base + MMDC_MAPSR;
35
36 /* Enable automatic power saving */
37 val = readl_relaxed(reg);
38 val &= ~(1 << BP_MMDC_MAPSR_PSD);
39 writel_relaxed(val, reg);
40
41 /* Ensure it's successfully enabled */
42 while (!(readl_relaxed(reg) & 1 << BP_MMDC_MAPSR_PSS) && --timeout)
43 cpu_relax();
44
45 if (unlikely(!timeout)) {
46 pr_warn("%s: failed to enable automatic power saving\n",
47 __func__);
48 return -EBUSY;
49 }
50
51 return 0;
52}
53
54static struct of_device_id imx_mmdc_dt_ids[] = {
55 { .compatible = "fsl,imx6q-mmdc", },
56 { /* sentinel */ }
57};
58
59static struct platform_driver imx_mmdc_driver = {
60 .driver = {
61 .name = "imx-mmdc",
62 .owner = THIS_MODULE,
63 .of_match_table = imx_mmdc_dt_ids,
64 },
65 .probe = imx_mmdc_probe,
66};
67
68static int __init imx_mmdc_init(void)
69{
70 return platform_driver_register(&imx_mmdc_driver);
71}
72postcore_initcall(imx_mmdc_init);
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
new file mode 100644
index 000000000000..ab98c6fec9eb
--- /dev/null
+++ b/arch/arm/mach-imx/platsmp.c
@@ -0,0 +1,85 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/init.h>
14#include <linux/smp.h>
15#include <asm/page.h>
16#include <asm/smp_scu.h>
17#include <asm/hardware/gic.h>
18#include <asm/mach/map.h>
19#include <mach/common.h>
20#include <mach/hardware.h>
21
22static void __iomem *scu_base;
23
24static struct map_desc scu_io_desc __initdata = {
25 /* .virtual and .pfn are run-time assigned */
26 .length = SZ_4K,
27 .type = MT_DEVICE,
28};
29
30void __init imx_scu_map_io(void)
31{
32 unsigned long base;
33
34 /* Get SCU base */
35 asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
36
37 scu_io_desc.virtual = IMX_IO_P2V(base);
38 scu_io_desc.pfn = __phys_to_pfn(base);
39 iotable_init(&scu_io_desc, 1);
40
41 scu_base = IMX_IO_ADDRESS(base);
42}
43
44void __cpuinit platform_secondary_init(unsigned int cpu)
45{
46 /*
47 * if any interrupts are already enabled for the primary
48 * core (e.g. timer irq), then they will not have been enabled
49 * for us: do so
50 */
51 gic_secondary_init(0);
52}
53
54int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
55{
56 imx_set_cpu_jump(cpu, v7_secondary_startup);
57 imx_enable_cpu(cpu, true);
58 return 0;
59}
60
61/*
62 * Initialise the CPU possible map early - this describes the CPUs
63 * which may be present or become present in the system.
64 */
65void __init smp_init_cpus(void)
66{
67 int i, ncores;
68
69 ncores = scu_get_core_count(scu_base);
70
71 for (i = 0; i < ncores; i++)
72 set_cpu_possible(i, true);
73
74 set_smp_cross_call(gic_raise_softirq);
75}
76
77void imx_smp_prepare(void)
78{
79 scu_enable(scu_base);
80}
81
82void __init platform_smp_prepare_cpus(unsigned int max_cpus)
83{
84 imx_smp_prepare();
85}
diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c
new file mode 100644
index 000000000000..f20f191d7cca
--- /dev/null
+++ b/arch/arm/mach-imx/pm-imx6q.c
@@ -0,0 +1,70 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/of.h>
16#include <linux/suspend.h>
17#include <asm/cacheflush.h>
18#include <asm/proc-fns.h>
19#include <asm/suspend.h>
20#include <asm/hardware/cache-l2x0.h>
21#include <mach/common.h>
22#include <mach/hardware.h>
23
24extern unsigned long phys_l2x0_saved_regs;
25
26static int imx6q_suspend_finish(unsigned long val)
27{
28 cpu_do_idle();
29 return 0;
30}
31
32static int imx6q_pm_enter(suspend_state_t state)
33{
34 switch (state) {
35 case PM_SUSPEND_MEM:
36 imx6q_set_lpm(STOP_POWER_OFF);
37 imx_gpc_pre_suspend();
38 imx_set_cpu_jump(0, v7_cpu_resume);
39 /* Zzz ... */
40 cpu_suspend(0, imx6q_suspend_finish);
41 imx_smp_prepare();
42 imx_gpc_post_resume();
43 break;
44 default:
45 return -EINVAL;
46 }
47
48 return 0;
49}
50
51static const struct platform_suspend_ops imx6q_pm_ops = {
52 .enter = imx6q_pm_enter,
53 .valid = suspend_valid_only_mem,
54};
55
56void __init imx6q_pm_init(void)
57{
58 /*
59 * The l2x0 core code provides an infrastucture to save and restore
60 * l2x0 registers across suspend/resume cycle. But because imx6q
61 * retains L2 content during suspend and needs to resume L2 before
62 * MMU is enabled, it can only utilize register saving support and
63 * have to take care of restoring on its own. So we save physical
64 * address of the data structure used by l2x0 core to save registers,
65 * and later restore the necessary ones in imx6q resume entry.
66 */
67 phys_l2x0_saved_regs = __pa(&l2x0_saved_regs);
68
69 suspend_set_ops(&imx6q_pm_ops);
70}
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
new file mode 100644
index 000000000000..36cacbd0dcc2
--- /dev/null
+++ b/arch/arm/mach-imx/src.c
@@ -0,0 +1,49 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/of.h>
16#include <linux/of_address.h>
17#include <asm/unified.h>
18
19#define SRC_SCR 0x000
20#define SRC_GPR1 0x020
21#define BP_SRC_SCR_CORE1_RST 14
22#define BP_SRC_SCR_CORE1_ENABLE 22
23
24static void __iomem *src_base;
25
26void imx_enable_cpu(int cpu, bool enable)
27{
28 u32 mask, val;
29
30 mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
31 val = readl_relaxed(src_base + SRC_SCR);
32 val = enable ? val | mask : val & ~mask;
33 writel_relaxed(val, src_base + SRC_SCR);
34}
35
36void imx_set_cpu_jump(int cpu, void *jump_addr)
37{
38 writel_relaxed(BSYM(virt_to_phys(jump_addr)),
39 src_base + SRC_GPR1 + cpu * 8);
40}
41
42void __init imx_src_init(void)
43{
44 struct device_node *np;
45
46 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-src");
47 src_base = of_iomap(np, 0);
48 WARN_ON(!src_base);
49}
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 0c427976d62f..0cc9094e5ee0 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -11,7 +11,6 @@
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14
15#include <linux/io.h> 14#include <linux/io.h>
16#include <linux/of_platform.h> 15#include <linux/of_platform.h>
17#include <linux/irqdomain.h> 16#include <linux/irqdomain.h>
diff --git a/arch/arm/mach-picoxcell/Makefile b/arch/arm/mach-picoxcell/Makefile
new file mode 100644
index 000000000000..c550b6363488
--- /dev/null
+++ b/arch/arm/mach-picoxcell/Makefile
@@ -0,0 +1,3 @@
1obj-y := common.o
2obj-y += time.o
3obj-y += io.o
diff --git a/arch/arm/mach-picoxcell/Makefile.boot b/arch/arm/mach-picoxcell/Makefile.boot
new file mode 100644
index 000000000000..b3271754e9fd
--- /dev/null
+++ b/arch/arm/mach-picoxcell/Makefile.boot
@@ -0,0 +1 @@
zreladdr-y := 0x00008000
diff --git a/arch/arm/mach-picoxcell/common.c b/arch/arm/mach-picoxcell/common.c
new file mode 100644
index 000000000000..34d08347be5f
--- /dev/null
+++ b/arch/arm/mach-picoxcell/common.c
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * All enquiries to support@picochip.com
9 */
10#include <linux/irq.h>
11#include <linux/irqdomain.h>
12#include <linux/of.h>
13#include <linux/of_address.h>
14#include <linux/of_platform.h>
15
16#include <asm/mach/arch.h>
17#include <asm/hardware/vic.h>
18
19#include <mach/map.h>
20#include <mach/picoxcell_soc.h>
21
22#include "common.h"
23
24static void __init picoxcell_init_machine(void)
25{
26 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
27}
28
29static const char *picoxcell_dt_match[] = {
30 "picochip,pc3x2",
31 "picochip,pc3x3",
32 NULL
33};
34
35static const struct of_device_id vic_of_match[] __initconst = {
36 { .compatible = "arm,pl192-vic" },
37 { /* Sentinel */ }
38};
39
40static void __init picoxcell_init_irq(void)
41{
42 vic_init(IO_ADDRESS(PICOXCELL_VIC0_BASE), 0, ~0, 0);
43 vic_init(IO_ADDRESS(PICOXCELL_VIC1_BASE), 32, ~0, 0);
44 irq_domain_generate_simple(vic_of_match, PICOXCELL_VIC0_BASE, 0);
45 irq_domain_generate_simple(vic_of_match, PICOXCELL_VIC1_BASE, 32);
46}
47
48DT_MACHINE_START(PICOXCELL, "Picochip picoXcell")
49 .map_io = picoxcell_map_io,
50 .nr_irqs = ARCH_NR_IRQS,
51 .init_irq = picoxcell_init_irq,
52 .timer = &picoxcell_timer,
53 .init_machine = picoxcell_init_machine,
54 .dt_compat = picoxcell_dt_match,
55MACHINE_END
diff --git a/arch/arm/mach-picoxcell/common.h b/arch/arm/mach-picoxcell/common.h
new file mode 100644
index 000000000000..5263f0fa095c
--- /dev/null
+++ b/arch/arm/mach-picoxcell/common.h
@@ -0,0 +1,18 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * All enquiries to support@picochip.com
9 */
10#ifndef __PICOXCELL_COMMON_H__
11#define __PICOXCELL_COMMON_H__
12
13#include <asm/mach/time.h>
14
15extern struct sys_timer picoxcell_timer;
16extern void picoxcell_map_io(void);
17
18#endif /* __PICOXCELL_COMMON_H__ */
diff --git a/arch/arm/mach-picoxcell/include/mach/debug-macro.S b/arch/arm/mach-picoxcell/include/mach/debug-macro.S
new file mode 100644
index 000000000000..8f2c234ed9d9
--- /dev/null
+++ b/arch/arm/mach-picoxcell/include/mach/debug-macro.S
@@ -0,0 +1,35 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Derived from arch/arm/mach-davinci/include/mach/debug-macro.S to use 32-bit
9 * accesses to the 8250.
10 */
11#include <linux/serial_reg.h>
12#include <mach/hardware.h>
13#include <mach/map.h>
14
15#define UART_SHIFT 2
16
17 .macro addruart, rp, rv
18 ldr \rv, =PHYS_TO_IO(PICOXCELL_UART1_BASE)
19 ldr \rp, =PICOXCELL_UART1_BASE
20 .endm
21
22 .macro senduart,rd,rx
23 str \rd, [\rx, #UART_TX << UART_SHIFT]
24 .endm
25
26 .macro busyuart,rd,rx
271002: ldr \rd, [\rx, #UART_LSR << UART_SHIFT]
28 and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
29 teq \rd, #UART_LSR_TEMT | UART_LSR_THRE
30 bne 1002b
31 .endm
32
33 /* The UART's don't have any flow control IO's wired up. */
34 .macro waituart,rd,rx
35 .endm
diff --git a/arch/arm/mach-picoxcell/include/mach/entry-macro.S b/arch/arm/mach-picoxcell/include/mach/entry-macro.S
new file mode 100644
index 000000000000..a6b09f75d9df
--- /dev/null
+++ b/arch/arm/mach-picoxcell/include/mach/entry-macro.S
@@ -0,0 +1,19 @@
1/*
2 * entry-macro.S
3 *
4 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
5 *
6 * Low-level IRQ helper macros for picoXcell platforms
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#include <mach/hardware.h>
13#include <mach/irqs.h>
14#include <mach/map.h>
15
16#define VA_VIC0 IO_ADDRESS(PICOXCELL_VIC0_BASE)
17#define VA_VIC1 IO_ADDRESS(PICOXCELL_VIC1_BASE)
18
19#include <asm/entry-macro-vic2.S>
diff --git a/arch/arm/mach-picoxcell/include/mach/gpio.h b/arch/arm/mach-picoxcell/include/mach/gpio.h
new file mode 100644
index 000000000000..40a8c178f10d
--- /dev/null
+++ b/arch/arm/mach-picoxcell/include/mach/gpio.h
@@ -0,0 +1 @@
/* empty */
diff --git a/arch/arm/mach-picoxcell/include/mach/hardware.h b/arch/arm/mach-picoxcell/include/mach/hardware.h
new file mode 100644
index 000000000000..70ff58192ec9
--- /dev/null
+++ b/arch/arm/mach-picoxcell/include/mach/hardware.h
@@ -0,0 +1,21 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This file contains the hardware definitions of the picoXcell SoC devices.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifndef __ASM_ARCH_HARDWARE_H
17#define __ASM_ARCH_HARDWARE_H
18
19#include <mach/picoxcell_soc.h>
20
21#endif
diff --git a/arch/arm/mach-picoxcell/include/mach/io.h b/arch/arm/mach-picoxcell/include/mach/io.h
new file mode 100644
index 000000000000..7573ec7d10a3
--- /dev/null
+++ b/arch/arm/mach-picoxcell/include/mach/io.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#ifndef __ASM_ARM_ARCH_IO_H
15#define __ASM_ARM_ARCH_IO_H
16
17/* No ioports, but needed for driver compatibility. */
18#define __io(a) __typesafe_io(a)
19/* No PCI possible on picoxcell. */
20#define __mem_pci(a) (a)
21
22#endif /* __ASM_ARM_ARCH_IO_H */
diff --git a/arch/arm/mach-picoxcell/include/mach/irqs.h b/arch/arm/mach-picoxcell/include/mach/irqs.h
new file mode 100644
index 000000000000..4d13ed970919
--- /dev/null
+++ b/arch/arm/mach-picoxcell/include/mach/irqs.h
@@ -0,0 +1,25 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This file contains the hardware definitions of the picoXcell SoC devices.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifndef __MACH_IRQS_H
17#define __MACH_IRQS_H
18
19#define ARCH_NR_IRQS 64
20#define NR_IRQS (128 + ARCH_NR_IRQS)
21
22#define IRQ_VIC0_BASE 0
23#define IRQ_VIC1_BASE 32
24
25#endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-picoxcell/include/mach/map.h b/arch/arm/mach-picoxcell/include/mach/map.h
new file mode 100644
index 000000000000..c06afad218bb
--- /dev/null
+++ b/arch/arm/mach-picoxcell/include/mach/map.h
@@ -0,0 +1,25 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#ifndef __PICOXCELL_MAP_H__
15#define __PICOXCELL_MAP_H__
16
17#define PHYS_TO_IO(x) (((x) & 0x00ffffff) | 0xfe000000)
18
19#ifdef __ASSEMBLY__
20#define IO_ADDRESS(x) PHYS_TO_IO((x))
21#else
22#define IO_ADDRESS(x) (void __iomem __force *)(PHYS_TO_IO((x)))
23#endif
24
25#endif /* __PICOXCELL_MAP_H__ */
diff --git a/arch/arm/mach-picoxcell/include/mach/memory.h b/arch/arm/mach-picoxcell/include/mach/memory.h
new file mode 100644
index 000000000000..40a8c178f10d
--- /dev/null
+++ b/arch/arm/mach-picoxcell/include/mach/memory.h
@@ -0,0 +1 @@
/* empty */
diff --git a/arch/arm/mach-picoxcell/include/mach/picoxcell_soc.h b/arch/arm/mach-picoxcell/include/mach/picoxcell_soc.h
new file mode 100644
index 000000000000..5566fc88ddbc
--- /dev/null
+++ b/arch/arm/mach-picoxcell/include/mach/picoxcell_soc.h
@@ -0,0 +1,25 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This file contains the hardware definitions of the picoXcell SoC devices.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifndef __PICOXCELL_SOC_H__
17#define __PICOXCELL_SOC_H__
18
19#define PICOXCELL_UART1_BASE 0x80230000
20#define PICOXCELL_PERIPH_BASE 0x80000000
21#define PICOXCELL_PERIPH_LENGTH SZ_4M
22#define PICOXCELL_VIC0_BASE 0x80060000
23#define PICOXCELL_VIC1_BASE 0x80064000
24
25#endif /* __PICOXCELL_SOC_H__ */
diff --git a/arch/arm/mach-picoxcell/include/mach/system.h b/arch/arm/mach-picoxcell/include/mach/system.h
new file mode 100644
index 000000000000..67c589b0c1bc
--- /dev/null
+++ b/arch/arm/mach-picoxcell/include/mach/system.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#ifndef __ASM_ARCH_SYSTEM_H
15#define __ASM_ARCH_SYSTEM_H
16
17static inline void arch_idle(void)
18{
19 /*
20 * This should do all the clock switching and wait for interrupt
21 * tricks.
22 */
23 cpu_do_idle();
24}
25
26static inline void arch_reset(int mode, const char *cmd)
27{
28 /* Watchdog reset to go here. */
29}
30
31#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-picoxcell/include/mach/timex.h b/arch/arm/mach-picoxcell/include/mach/timex.h
new file mode 100644
index 000000000000..6c540a69f405
--- /dev/null
+++ b/arch/arm/mach-picoxcell/include/mach/timex.h
@@ -0,0 +1,25 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef __TIMEX_H__
19#define __TIMEX_H__
20
21/* Bogus value to allow the kernel to compile. */
22#define CLOCK_TICK_RATE 1000000
23
24#endif /* __TIMEX_H__ */
25
diff --git a/arch/arm/mach-picoxcell/include/mach/uncompress.h b/arch/arm/mach-picoxcell/include/mach/uncompress.h
new file mode 100644
index 000000000000..b60b19d1d739
--- /dev/null
+++ b/arch/arm/mach-picoxcell/include/mach/uncompress.h
@@ -0,0 +1,21 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#define putc(c)
19#define flush()
20#define arch_decomp_setup()
21#define arch_decomp_wdog()
diff --git a/arch/arm/mach-picoxcell/include/mach/vmalloc.h b/arch/arm/mach-picoxcell/include/mach/vmalloc.h
new file mode 100644
index 000000000000..0216cc4b1f0b
--- /dev/null
+++ b/arch/arm/mach-picoxcell/include/mach/vmalloc.h
@@ -0,0 +1,14 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#define VMALLOC_END 0xfe000000UL
diff --git a/arch/arm/mach-picoxcell/io.c b/arch/arm/mach-picoxcell/io.c
new file mode 100644
index 000000000000..39e9b9e8cc37
--- /dev/null
+++ b/arch/arm/mach-picoxcell/io.c
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * All enquiries to support@picochip.com
9 */
10#include <linux/io.h>
11#include <linux/mm.h>
12#include <linux/module.h>
13#include <linux/of.h>
14
15#include <asm/mach/map.h>
16
17#include <mach/map.h>
18#include <mach/picoxcell_soc.h>
19
20#include "common.h"
21
22void __init picoxcell_map_io(void)
23{
24 struct map_desc io_map = {
25 .virtual = PHYS_TO_IO(PICOXCELL_PERIPH_BASE),
26 .pfn = __phys_to_pfn(PICOXCELL_PERIPH_BASE),
27 .length = PICOXCELL_PERIPH_LENGTH,
28 .type = MT_DEVICE,
29 };
30
31 iotable_init(&io_map, 1);
32}
diff --git a/arch/arm/mach-picoxcell/time.c b/arch/arm/mach-picoxcell/time.c
new file mode 100644
index 000000000000..90a554ff4499
--- /dev/null
+++ b/arch/arm/mach-picoxcell/time.c
@@ -0,0 +1,132 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * All enquiries to support@picochip.com
9 */
10#include <linux/dw_apb_timer.h>
11#include <linux/of.h>
12#include <linux/of_address.h>
13#include <linux/of_irq.h>
14#include <linux/sched.h>
15
16#include <asm/mach/time.h>
17#include <asm/sched_clock.h>
18
19#include "common.h"
20
21static void timer_get_base_and_rate(struct device_node *np,
22 void __iomem **base, u32 *rate)
23{
24 *base = of_iomap(np, 0);
25
26 if (!*base)
27 panic("Unable to map regs for %s", np->name);
28
29 if (of_property_read_u32(np, "clock-freq", rate))
30 panic("No clock-freq property for %s", np->name);
31}
32
33static void picoxcell_add_clockevent(struct device_node *event_timer)
34{
35 void __iomem *iobase;
36 struct dw_apb_clock_event_device *ced;
37 u32 irq, rate;
38
39 irq = irq_of_parse_and_map(event_timer, 0);
40 if (irq == NO_IRQ)
41 panic("No IRQ for clock event timer");
42
43 timer_get_base_and_rate(event_timer, &iobase, &rate);
44
45 ced = dw_apb_clockevent_init(0, event_timer->name, 300, iobase, irq,
46 rate);
47 if (!ced)
48 panic("Unable to initialise clockevent device");
49
50 dw_apb_clockevent_register(ced);
51}
52
53static void picoxcell_add_clocksource(struct device_node *source_timer)
54{
55 void __iomem *iobase;
56 struct dw_apb_clocksource *cs;
57 u32 rate;
58
59 timer_get_base_and_rate(source_timer, &iobase, &rate);
60
61 cs = dw_apb_clocksource_init(300, source_timer->name, iobase, rate);
62 if (!cs)
63 panic("Unable to initialise clocksource device");
64
65 dw_apb_clocksource_start(cs);
66 dw_apb_clocksource_register(cs);
67}
68
69static DEFINE_CLOCK_DATA(cd);
70static void __iomem *sched_io_base;
71
72unsigned long long notrace sched_clock(void)
73{
74 cycle_t cyc = sched_io_base ? __raw_readl(sched_io_base) : 0;
75
76 return cyc_to_sched_clock(&cd, cyc, (u32)~0);
77}
78
79static void notrace picoxcell_update_sched_clock(void)
80{
81 cycle_t cyc = sched_io_base ? __raw_readl(sched_io_base) : 0;
82
83 update_sched_clock(&cd, cyc, (u32)~0);
84}
85
86static const struct of_device_id picoxcell_rtc_ids[] __initconst = {
87 { .compatible = "picochip,pc3x2-rtc" },
88 { /* Sentinel */ },
89};
90
91static void picoxcell_init_sched_clock(void)
92{
93 struct device_node *sched_timer;
94 u32 rate;
95
96 sched_timer = of_find_matching_node(NULL, picoxcell_rtc_ids);
97 if (!sched_timer)
98 panic("No RTC for sched clock to use");
99
100 timer_get_base_and_rate(sched_timer, &sched_io_base, &rate);
101 of_node_put(sched_timer);
102
103 init_sched_clock(&cd, picoxcell_update_sched_clock, 32, rate);
104}
105
106static const struct of_device_id picoxcell_timer_ids[] __initconst = {
107 { .compatible = "picochip,pc3x2-timer" },
108 {},
109};
110
111static void __init picoxcell_timer_init(void)
112{
113 struct device_node *event_timer, *source_timer;
114
115 event_timer = of_find_matching_node(NULL, picoxcell_timer_ids);
116 if (!event_timer)
117 panic("No timer for clockevent");
118 picoxcell_add_clockevent(event_timer);
119
120 source_timer = of_find_matching_node(event_timer, picoxcell_timer_ids);
121 if (!source_timer)
122 panic("No timer for clocksource");
123 picoxcell_add_clocksource(source_timer);
124
125 of_node_put(source_timer);
126
127 picoxcell_init_sched_clock();
128}
129
130struct sys_timer picoxcell_timer = {
131 .init = picoxcell_timer_init,
132};
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 88633fe01a5d..67f75a0b66d6 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -819,10 +819,10 @@ config CACHE_FEROCEON_L2_WRITETHROUGH
819config CACHE_L2X0 819config CACHE_L2X0
820 bool "Enable the L2x0 outer cache controller" 820 bool "Enable the L2x0 outer cache controller"
821 depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ 821 depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
822 REALVIEW_EB_A9MP || SOC_IMX35 || SOC_IMX31 || MACH_REALVIEW_PBX || \ 822 REALVIEW_EB_A9MP || ARCH_IMX_V6_V7 || MACH_REALVIEW_PBX || \
823 ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \ 823 ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \
824 ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || \ 824 ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || \
825 ARCH_PRIMA2 || ARCH_ZYNQ || ARCH_CNS3XXX 825 ARCH_PRIMA2 || ARCH_ZYNQ || ARCH_CNS3XXX || ARCH_HIGHBANK
826 default y 826 default y
827 select OUTER_CACHE 827 select OUTER_CACHE
828 select OUTER_CACHE_SYNC 828 select OUTER_CACHE_SYNC
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 4bdc975581eb..a08a95107a63 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -6,7 +6,7 @@ menu "Freescale MXC Implementations"
6 6
7choice 7choice
8 prompt "Freescale CPU family:" 8 prompt "Freescale CPU family:"
9 default ARCH_MX3 9 default ARCH_IMX_V6_V7
10 10
11config ARCH_IMX_V4_V5 11config ARCH_IMX_V4_V5
12 bool "i.MX1, i.MX21, i.MX25, i.MX27" 12 bool "i.MX1, i.MX21, i.MX25, i.MX27"
@@ -16,10 +16,13 @@ config ARCH_IMX_V4_V5
16 This enables support for systems based on the Freescale i.MX ARMv4 16 This enables support for systems based on the Freescale i.MX ARMv4
17 and ARMv5 SoCs 17 and ARMv5 SoCs
18 18
19config ARCH_MX3 19config ARCH_IMX_V6_V7
20 bool "MX3-based" 20 bool "i.MX3, i.MX6"
21 select AUTO_ZRELADDR if !ZBOOT_ROM
22 select ARM_PATCH_PHYS_VIRT
21 help 23 help
22 This enables support for systems based on the Freescale i.MX3 family 24 This enables support for systems based on the Freescale i.MX3 and i.MX6
25 family.
23 26
24config ARCH_MX5 27config ARCH_MX5
25 bool "i.MX50, i.MX51, i.MX53" 28 bool "i.MX50, i.MX51, i.MX53"
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index d53c35fe2ea7..b9f0f5f499a4 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -5,7 +5,7 @@
5# Common support 5# Common support
6obj-y := clock.o time.o devices.o cpu.o system.o irq-common.o 6obj-y := clock.o time.o devices.o cpu.o system.o irq-common.o
7 7
8# MX51 uses the TZIC interrupt controller, older platforms use AVIC 8obj-$(CONFIG_ARM_GIC) += gic.o
9obj-$(CONFIG_MXC_TZIC) += tzic.o 9obj-$(CONFIG_MXC_TZIC) += tzic.o
10obj-$(CONFIG_MXC_AVIC) += avic.o 10obj-$(CONFIG_MXC_AVIC) += avic.o
11 11
diff --git a/arch/arm/plat-mxc/gic.c b/arch/arm/plat-mxc/gic.c
new file mode 100644
index 000000000000..b3b8eed263b8
--- /dev/null
+++ b/arch/arm/plat-mxc/gic.c
@@ -0,0 +1,48 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/io.h>
14#include <asm/exception.h>
15#include <asm/localtimer.h>
16#include <asm/hardware/gic.h>
17#ifdef CONFIG_SMP
18#include <asm/smp.h>
19#endif
20
21asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
22{
23 u32 irqstat, irqnr;
24
25 do {
26 irqstat = readl_relaxed(gic_cpu_base_addr + GIC_CPU_INTACK);
27 irqnr = irqstat & 0x3ff;
28 if (irqnr == 1023)
29 break;
30
31 if (irqnr > 29 && irqnr < 1021)
32 handle_IRQ(irqnr, regs);
33#ifdef CONFIG_SMP
34 else if (irqnr < 16) {
35 writel_relaxed(irqstat, gic_cpu_base_addr +
36 GIC_CPU_EOI);
37 handle_IPI(irqnr, regs);
38 }
39#endif
40#ifdef CONFIG_LOCAL_TIMERS
41 else if (irqnr == 29) {
42 writel_relaxed(irqstat, gic_cpu_base_addr +
43 GIC_CPU_EOI);
44 handle_local_timer(regs);
45 }
46#endif
47 } while (1);
48}
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index c850af3650ea..83b745a5e1b7 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -13,6 +13,7 @@
13 13
14struct platform_device; 14struct platform_device;
15struct clk; 15struct clk;
16enum mxc_cpu_pwr_mode;
16 17
17extern void mx1_map_io(void); 18extern void mx1_map_io(void);
18extern void mx21_map_io(void); 19extern void mx21_map_io(void);
@@ -66,6 +67,7 @@ extern int mx53_clocks_init(unsigned long ckil, unsigned long osc,
66 unsigned long ckih1, unsigned long ckih2); 67 unsigned long ckih1, unsigned long ckih2);
67extern int mx51_clocks_init_dt(void); 68extern int mx51_clocks_init_dt(void);
68extern int mx53_clocks_init_dt(void); 69extern int mx53_clocks_init_dt(void);
70extern int mx6q_clocks_init(void);
69extern struct platform_device *mxc_register_gpio(char *name, int id, 71extern struct platform_device *mxc_register_gpio(char *name, int id,
70 resource_size_t iobase, resource_size_t iosize, int irq, int irq_high); 72 resource_size_t iobase, resource_size_t iosize, int irq, int irq_high);
71extern void mxc_set_cpu_type(unsigned int type); 73extern void mxc_set_cpu_type(unsigned int type);
@@ -88,6 +90,7 @@ extern void imx_print_silicon_rev(const char *cpu, int srev);
88 90
89void avic_handle_irq(struct pt_regs *); 91void avic_handle_irq(struct pt_regs *);
90void tzic_handle_irq(struct pt_regs *); 92void tzic_handle_irq(struct pt_regs *);
93void gic_handle_irq(struct pt_regs *);
91 94
92#define imx1_handle_irq avic_handle_irq 95#define imx1_handle_irq avic_handle_irq
93#define imx21_handle_irq avic_handle_irq 96#define imx21_handle_irq avic_handle_irq
@@ -98,10 +101,36 @@ void tzic_handle_irq(struct pt_regs *);
98#define imx50_handle_irq tzic_handle_irq 101#define imx50_handle_irq tzic_handle_irq
99#define imx51_handle_irq tzic_handle_irq 102#define imx51_handle_irq tzic_handle_irq
100#define imx53_handle_irq tzic_handle_irq 103#define imx53_handle_irq tzic_handle_irq
104#define imx6q_handle_irq gic_handle_irq
101 105
106extern void imx_enable_cpu(int cpu, bool enable);
107extern void imx_set_cpu_jump(int cpu, void *jump_addr);
108#ifdef CONFIG_DEBUG_LL
109extern void imx_lluart_map_io(void);
110#else
111static inline void imx_lluart_map_io(void) {}
112#endif
113extern void v7_cpu_resume(void);
114extern u32 *pl310_get_save_ptr(void);
115#ifdef CONFIG_SMP
116extern void v7_secondary_startup(void);
117extern void imx_scu_map_io(void);
118extern void imx_smp_prepare(void);
119#else
120static inline void imx_scu_map_io(void) {}
121static inline void imx_smp_prepare(void) {}
122#endif
123extern void imx_enable_cpu(int cpu, bool enable);
124extern void imx_set_cpu_jump(int cpu, void *jump_addr);
125extern void imx_src_init(void);
126extern void imx_gpc_init(void);
127extern void imx_gpc_pre_suspend(void);
128extern void imx_gpc_post_resume(void);
102extern void imx51_babbage_common_init(void); 129extern void imx51_babbage_common_init(void);
103extern void imx53_ard_common_init(void); 130extern void imx53_ard_common_init(void);
104extern void imx53_evk_common_init(void); 131extern void imx53_evk_common_init(void);
105extern void imx53_qsb_common_init(void); 132extern void imx53_qsb_common_init(void);
106extern void imx53_smd_common_init(void); 133extern void imx53_smd_common_init(void);
134extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
135extern void imx6q_pm_init(void);
107#endif 136#endif
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
index 72986013c1fb..6e192c4a391a 100644
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -24,6 +24,8 @@
24#define UART_PADDR MX51_UART1_BASE_ADDR 24#define UART_PADDR MX51_UART1_BASE_ADDR
25#elif defined (CONFIG_DEBUG_IMX50_IMX53_UART) 25#elif defined (CONFIG_DEBUG_IMX50_IMX53_UART)
26#define UART_PADDR MX53_UART1_BASE_ADDR 26#define UART_PADDR MX53_UART1_BASE_ADDR
27#elif defined (CONFIG_DEBUG_IMX6Q_UART)
28#define UART_PADDR MX6Q_UART4_BASE_ADDR
27#endif 29#endif
28 30
29#define UART_VADDR IMX_IO_ADDRESS(UART_PADDR) 31#define UART_VADDR IMX_IO_ADDRESS(UART_PADDR)
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
index 842fbcb0d6cc..9fe0dfcf4e7e 100644
--- a/arch/arm/plat-mxc/include/mach/entry-macro.S
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
@@ -22,3 +22,9 @@
22 22
23 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp 23 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
24 .endm 24 .endm
25
26 .macro test_for_ipi, irqnr, irqstat, base, tmp
27 .endm
28
29 .macro test_for_ltirq, irqnr, irqstat, base, tmp
30 .endm
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
index eba3118adfbb..a599f01f8b92 100644
--- a/arch/arm/plat-mxc/include/mach/hardware.h
+++ b/arch/arm/plat-mxc/include/mach/hardware.h
@@ -91,6 +91,11 @@
91 * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000 91 * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
92 * AIPS1 0x53f00000+0x100000 -> 0xf5700000+0x100000 92 * AIPS1 0x53f00000+0x100000 -> 0xf5700000+0x100000
93 * AIPS2 0x63f00000+0x100000 -> 0xf5300000+0x100000 93 * AIPS2 0x63f00000+0x100000 -> 0xf5300000+0x100000
94 * mx6q:
95 * SCU 0x00a00000+0x001000 -> 0xf4000000+0x001000
96 * CCM 0x020c4000+0x004000 -> 0xf42c4000+0x004000
97 * ANATOP 0x020c8000+0x001000 -> 0xf42c8000+0x001000
98 * UART4 0x021f0000+0x004000 -> 0xf42f0000+0x004000
94 */ 99 */
95#define IMX_IO_P2V(x) ( \ 100#define IMX_IO_P2V(x) ( \
96 0xf4000000 + \ 101 0xf4000000 + \
@@ -102,6 +107,7 @@
102 107
103#include <mach/mxc.h> 108#include <mach/mxc.h>
104 109
110#include <mach/mx6q.h>
105#include <mach/mx50.h> 111#include <mach/mx50.h>
106#include <mach/mx51.h> 112#include <mach/mx51.h>
107#include <mach/mx53.h> 113#include <mach/mx53.h>
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index 00e812bbd81d..fd9efb044656 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -14,9 +14,15 @@
14#include <asm-generic/gpio.h> 14#include <asm-generic/gpio.h>
15 15
16/* 16/*
17 * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64 17 * SoCs with GIC interrupt controller have 160 IRQs, those with TZIC
18 * have 128 IRQs, and those with AVIC have 64.
19 *
20 * To support single image, the biggest number should be defined on
21 * top of the list.
18 */ 22 */
19#ifdef CONFIG_MXC_TZIC 23#if defined CONFIG_ARM_GIC
24#define MXC_INTERNAL_IRQS 160
25#elif defined CONFIG_MXC_TZIC
20#define MXC_INTERNAL_IRQS 128 26#define MXC_INTERNAL_IRQS 128
21#else 27#else
22#define MXC_INTERNAL_IRQS 64 28#define MXC_INTERNAL_IRQS 64
diff --git a/arch/arm/plat-mxc/include/mach/mx6q.h b/arch/arm/plat-mxc/include/mach/mx6q.h
new file mode 100644
index 000000000000..254a561a2799
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx6q.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#ifndef __MACH_MX6Q_H__
14#define __MACH_MX6Q_H__
15
16#define MX6Q_IO_P2V(x) IMX_IO_P2V(x)
17#define MX6Q_IO_ADDRESS(x) IOMEM(MX6Q_IO_P2V(x))
18
19/*
20 * The following are the blocks that need to be statically mapped.
21 * For other blocks, the base address really should be retrieved from
22 * device tree.
23 */
24#define MX6Q_SCU_BASE_ADDR 0x00a00000
25#define MX6Q_SCU_SIZE 0x1000
26#define MX6Q_CCM_BASE_ADDR 0x020c4000
27#define MX6Q_CCM_SIZE 0x4000
28#define MX6Q_ANATOP_BASE_ADDR 0x020c8000
29#define MX6Q_ANATOP_SIZE 0x1000
30#define MX6Q_UART4_BASE_ADDR 0x021f0000
31#define MX6Q_UART4_SIZE 0x4000
32
33#endif /* __MACH_MX6Q_H__ */