aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/fsl.txt7
-rw-r--r--MAINTAINERS7
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/Kconfig.debug124
-rw-r--r--arch/arm/Makefile2
-rw-r--r--arch/arm/boot/dts/imx6q-sabreauto.dts62
-rw-r--r--arch/arm/boot/dts/imx6q.dtsi575
-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-mxs/include/mach/debug-macro.S12
-rw-r--r--arch/arm/mach-realview/include/mach/debug-macro.S17
-rw-r--r--arch/arm/mm/Kconfig2
-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.S40
-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
-rw-r--r--arch/arm/plat-samsung/Kconfig7
34 files changed, 3662 insertions, 80 deletions
diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt
index e2401cd632a..c9848ad0e2e 100644
--- a/Documentation/devicetree/bindings/arm/fsl.txt
+++ b/Documentation/devicetree/bindings/arm/fsl.txt
@@ -1,3 +1,6 @@
1Freescale i.MX Platforms Device Tree Bindings
2-----------------------------------------------
3
1i.MX51 Babbage Board 4i.MX51 Babbage Board
2Required root node properties: 5Required root node properties:
3 - compatible = "fsl,imx51-babbage", "fsl,imx51"; 6 - compatible = "fsl,imx51-babbage", "fsl,imx51";
@@ -17,3 +20,7 @@ Required root node properties:
17i.MX53 Smart Mobile Reference Design Board 20i.MX53 Smart Mobile Reference Design Board
18Required root node properties: 21Required root node properties:
19 - compatible = "fsl,imx53-smd", "fsl,imx53"; 22 - compatible = "fsl,imx53-smd", "fsl,imx53";
23
24i.MX6 Quad SABRE Automotive Board
25Required root node properties:
26 - compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
diff --git a/MAINTAINERS b/MAINTAINERS
index 5066335b97d..1ba8fffdd7e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -793,6 +793,13 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
793S: Maintained 793S: Maintained
794F: arch/arm/mach-mx5/ 794F: arch/arm/mach-mx5/
795 795
796ARM/FREESCALE IMX6
797M: Shawn Guo <shawn.guo@linaro.org>
798L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
799S: Maintained
800T: git git://git.linaro.org/people/shawnguo/linux-2.6.git
801F: arch/arm/mach-imx/*imx6*
802
796ARM/GLOMATION GESBC9312SX MACHINE SUPPORT 803ARM/GLOMATION GESBC9312SX MACHINE SUPPORT
797M: Lennert Buytenhek <kernel@wantstofly.org> 804M: Lennert Buytenhek <kernel@wantstofly.org>
798L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 805L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4fe1db17146..f41fe7a4001 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1435,7 +1435,7 @@ config SMP
1435 depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \ 1435 depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
1436 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \ 1436 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
1437 ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \ 1437 ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
1438 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || ARCH_HIGHBANK 1438 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || ARCH_HIGHBANK || SOC_IMX6Q
1439 select USE_GENERIC_SMP_HELPERS 1439 select USE_GENERIC_SMP_HELPERS
1440 select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP 1440 select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
1441 help 1441 help
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 4bb7eb90f07..c865b927136 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -135,6 +135,118 @@ choice
135 Say Y here if you want the debug print routines to direct 135 Say Y here if you want the debug print routines to direct
136 their output to the UART on Highbank based devices. 136 their output to the UART on Highbank based devices.
137 137
138 config DEBUG_IMX1_UART
139 bool "i.MX1 Debug UART"
140 depends on SOC_IMX1
141 help
142 Say Y here if you want kernel low-level debugging support
143 on i.MX1.
144
145 config DEBUG_IMX23_UART
146 bool "i.MX23 Debug UART"
147 depends on SOC_IMX23
148 help
149 Say Y here if you want kernel low-level debugging support
150 on i.MX23.
151
152 config DEBUG_IMX25_UART
153 bool "i.MX25 Debug UART"
154 depends on SOC_IMX25
155 help
156 Say Y here if you want kernel low-level debugging support
157 on i.MX25.
158
159 config DEBUG_IMX21_IMX27_UART
160 bool "i.MX21 and i.MX27 Debug UART"
161 depends on SOC_IMX21 || SOC_IMX27
162 help
163 Say Y here if you want kernel low-level debugging support
164 on i.MX21 or i.MX27.
165
166 config DEBUG_IMX28_UART
167 bool "i.MX28 Debug UART"
168 depends on SOC_IMX28
169 help
170 Say Y here if you want kernel low-level debugging support
171 on i.MX28.
172
173 config DEBUG_IMX31_IMX35_UART
174 bool "i.MX31 and i.MX35 Debug UART"
175 depends on SOC_IMX31 || SOC_IMX35
176 help
177 Say Y here if you want kernel low-level debugging support
178 on i.MX31 or i.MX35.
179
180 config DEBUG_IMX51_UART
181 bool "i.MX51 Debug UART"
182 depends on SOC_IMX51
183 help
184 Say Y here if you want kernel low-level debugging support
185 on i.MX51.
186
187 config DEBUG_IMX50_IMX53_UART
188 bool "i.MX50 and i.MX53 Debug UART"
189 depends on SOC_IMX50 || SOC_IMX53
190 help
191 Say Y here if you want kernel low-level debugging support
192 on i.MX50 or i.MX53.
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
201 config DEBUG_S3C_UART0
202 depends on PLAT_SAMSUNG
203 bool "Use S3C UART 0 for low-level debug"
204 help
205 Say Y here if you want the debug print routines to direct
206 their output to UART 0. The port must have been initialised
207 by the boot-loader before use.
208
209 The uncompressor code port configuration is now handled
210 by CONFIG_S3C_LOWLEVEL_UART_PORT.
211
212 config DEBUG_S3C_UART1
213 depends on PLAT_SAMSUNG
214 bool "Use S3C UART 1 for low-level debug"
215 help
216 Say Y here if you want the debug print routines to direct
217 their output to UART 1. The port must have been initialised
218 by the boot-loader before use.
219
220 The uncompressor code port configuration is now handled
221 by CONFIG_S3C_LOWLEVEL_UART_PORT.
222
223 config DEBUG_S3C_UART2
224 depends on PLAT_SAMSUNG
225 bool "Use S3C UART 2 for low-level debug"
226 help
227 Say Y here if you want the debug print routines to direct
228 their output to UART 2. The port must have been initialised
229 by the boot-loader before use.
230
231 The uncompressor code port configuration is now handled
232 by CONFIG_S3C_LOWLEVEL_UART_PORT.
233
234 config DEBUG_REALVIEW_STD_PORT
235 bool "RealView Default UART"
236 depends on ARCH_REALVIEW
237 help
238 Say Y here if you want the debug print routines to direct
239 their output to the serial port on RealView EB, PB11MP, PBA8
240 and PBX platforms.
241
242 config DEBUG_REALVIEW_PB1176_PORT
243 bool "RealView PB1176 UART"
244 depends on MACH_REALVIEW_PB1176
245 help
246 Say Y here if you want the debug print routines to direct
247 their output to the standard serial port on the RealView
248 PB1176 platform.
249
138endchoice 250endchoice
139 251
140config EARLY_PRINTK 252config EARLY_PRINTK
@@ -153,18 +265,6 @@ config OC_ETM
153 buffer driver that will allow you to collect traces of the 265 buffer driver that will allow you to collect traces of the
154 kernel code. 266 kernel code.
155 267
156config DEBUG_S3C_UART
157 depends on PLAT_SAMSUNG
158 int "S3C UART to use for low-level debug"
159 default "0"
160 help
161 Choice for UART for kernel low-level using S3C UARTS,
162 should be between zero and two. The port must have been
163 initialised by the boot-loader before use.
164
165 The uncompressor code port configuration is now handled
166 by CONFIG_S3C_LOWLEVEL_UART_PORT.
167
168config ARM_KPROBES_TEST 268config ARM_KPROBES_TEST
169 tristate "Kprobes test module" 269 tristate "Kprobes test module"
170 depends on KPROBES && MODULES 270 depends on KPROBES && MODULES
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index e775f93844a..ae458aee8b6 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -159,7 +159,7 @@ machine-$(CONFIG_ARCH_MMP) := mmp
159machine-$(CONFIG_ARCH_MSM) := msm 159machine-$(CONFIG_ARCH_MSM) := msm
160machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0 160machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
161machine-$(CONFIG_ARCH_IMX_V4_V5) := imx 161machine-$(CONFIG_ARCH_IMX_V4_V5) := imx
162machine-$(CONFIG_ARCH_MX3) := imx 162machine-$(CONFIG_ARCH_IMX_V6_V7) := imx
163machine-$(CONFIG_ARCH_MX5) := mx5 163machine-$(CONFIG_ARCH_MX5) := mx5
164machine-$(CONFIG_ARCH_MXS) := mxs 164machine-$(CONFIG_ARCH_MXS) := mxs
165machine-$(CONFIG_ARCH_NETX) := netx 165machine-$(CONFIG_ARCH_NETX) := netx
diff --git a/arch/arm/boot/dts/imx6q-sabreauto.dts b/arch/arm/boot/dts/imx6q-sabreauto.dts
new file mode 100644
index 00000000000..072974e443f
--- /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 00000000000..7dda599558c
--- /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/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index b4e1bf8757c..b1f782f07f1 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
@@ -591,4 +603,20 @@ config MACH_VPR200
591 Include support for VPR200 platform. This includes specific 603 Include support for VPR200 platform. This includes specific
592 configurations for the board and its peripherals. 604 configurations for the board and its peripherals.
593 605
606comment "i.MX6 family:"
607
608config SOC_IMX6Q
609 bool "i.MX6 Quad support"
610 select ARM_GIC
611 select CACHE_L2X0
612 select CPU_V7
613 select HAVE_ARM_SCU
614 select HAVE_IMX_GPC
615 select HAVE_IMX_MMDC
616 select HAVE_IMX_SRC
617 select USE_OF
618
619 help
620 This enables support for Freescale i.MX6 Quad processor.
621
594endif 622endif
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 116d4b2d281..aba73214c2a 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 ebee18b3884..136cfc6f2f8 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 00000000000..e0b926dfece
--- /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 00000000000..e1537f9e45b
--- /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 00000000000..6229efbc70c
--- /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 00000000000..89493abd497
--- /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 00000000000..d4ab6f29a76
--- /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 00000000000..3a163515d41
--- /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 00000000000..8bf5fa34948
--- /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 00000000000..c461e98496c
--- /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 00000000000..ab98c6fec9e
--- /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 00000000000..f20f191d7cc
--- /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 00000000000..36cacbd0dcc
--- /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-mxs/include/mach/debug-macro.S b/arch/arm/mach-mxs/include/mach/debug-macro.S
index 714570d8366..90c6b7836ad 100644
--- a/arch/arm/mach-mxs/include/mach/debug-macro.S
+++ b/arch/arm/mach-mxs/include/mach/debug-macro.S
@@ -14,17 +14,9 @@
14#include <mach/mx23.h> 14#include <mach/mx23.h>
15#include <mach/mx28.h> 15#include <mach/mx28.h>
16 16
17#ifdef CONFIG_SOC_IMX23 17#ifdef CONFIG_DEBUG_IMX23_UART
18#ifdef UART_PADDR
19#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
20#endif
21#define UART_PADDR MX23_DUART_BASE_ADDR 18#define UART_PADDR MX23_DUART_BASE_ADDR
22#endif 19#elif defined (CONFIG_DEBUG_IMX28_UART)
23
24#ifdef CONFIG_SOC_IMX28
25#ifdef UART_PADDR
26#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
27#endif
28#define UART_PADDR MX28_DUART_BASE_ADDR 20#define UART_PADDR MX28_DUART_BASE_ADDR
29#endif 21#endif
30 22
diff --git a/arch/arm/mach-realview/include/mach/debug-macro.S b/arch/arm/mach-realview/include/mach/debug-macro.S
index fb4901c4ef0..8cc372dc66a 100644
--- a/arch/arm/mach-realview/include/mach/debug-macro.S
+++ b/arch/arm/mach-realview/include/mach/debug-macro.S
@@ -10,23 +10,10 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#if defined(CONFIG_MACH_REALVIEW_EB) || \ 13#ifdef CONFIG_DEBUG_REALVIEW_STD_PORT
14 defined(CONFIG_MACH_REALVIEW_PB11MP) || \
15 defined(CONFIG_MACH_REALVIEW_PBA8) || \
16 defined(CONFIG_MACH_REALVIEW_PBX)
17#ifndef DEBUG_LL_UART_OFFSET
18#define DEBUG_LL_UART_OFFSET 0x00009000 14#define DEBUG_LL_UART_OFFSET 0x00009000
19#elif DEBUG_LL_UART_OFFSET != 0x00009000 15#elif defined(CONFIG_DEBUG_REALVIEW_PB1176_PORT)
20#warning "DEBUG_LL_UART_OFFSET already defined to a different value"
21#endif
22#endif
23
24#ifdef CONFIG_MACH_REALVIEW_PB1176
25#ifndef DEBUG_LL_UART_OFFSET
26#define DEBUG_LL_UART_OFFSET 0x0010c000 16#define DEBUG_LL_UART_OFFSET 0x0010c000
27#elif DEBUG_LL_UART_OFFSET != 0x0010c000
28#warning "DEBUG_LL_UART_OFFSET already defined to a different value"
29#endif
30#endif 17#endif
31 18
32#ifndef DEBUG_LL_UART_OFFSET 19#ifndef DEBUG_LL_UART_OFFSET
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 7d5fff7b363..67f75a0b66d 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -819,7 +819,7 @@ 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 || ARCH_HIGHBANK 825 ARCH_PRIMA2 || ARCH_ZYNQ || ARCH_CNS3XXX || ARCH_HIGHBANK
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 502e45f0317..2704951d8cd 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 d53c35fe2ea..b9f0f5f499a 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 00000000000..b3b8eed263b
--- /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 c850af3650e..83b745a5e1b 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 a3045937fc2..6e192c4a391 100644
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -12,44 +12,20 @@
12 */ 12 */
13#include <mach/hardware.h> 13#include <mach/hardware.h>
14 14
15#ifdef CONFIG_SOC_IMX1 15#ifdef CONFIG_DEBUG_IMX1_UART
16#define UART_PADDR MX1_UART1_BASE_ADDR 16#define UART_PADDR MX1_UART1_BASE_ADDR
17#endif 17#elif defined (CONFIG_DEBUG_IMX25_UART)
18
19#ifdef CONFIG_SOC_IMX25
20#ifdef UART_PADDR
21#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
22#endif
23#define UART_PADDR MX25_UART1_BASE_ADDR 18#define UART_PADDR MX25_UART1_BASE_ADDR
24#endif 19#elif defined (CONFIG_DEBUG_IMX21_IMX27_UART)
25
26#if defined(CONFIG_SOC_IMX21) || defined (CONFIG_SOC_IMX27)
27#ifdef UART_PADDR
28#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
29#endif
30#define UART_PADDR MX2x_UART1_BASE_ADDR 20#define UART_PADDR MX2x_UART1_BASE_ADDR
31#endif 21#elif defined (CONFIG_DEBUG_IMX31_IMX35_UART)
32
33#if defined(CONFIG_SOC_IMX31) || defined(CONFIG_SOC_IMX35)
34#ifdef UART_PADDR
35#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
36#endif
37#define UART_PADDR MX3x_UART1_BASE_ADDR 22#define UART_PADDR MX3x_UART1_BASE_ADDR
38#endif 23#elif defined (CONFIG_DEBUG_IMX51_UART)
39
40#ifdef CONFIG_SOC_IMX51
41#ifdef UART_PADDR
42#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
43#endif
44#define UART_PADDR MX51_UART1_BASE_ADDR 24#define UART_PADDR MX51_UART1_BASE_ADDR
45#endif 25#elif defined (CONFIG_DEBUG_IMX50_IMX53_UART)
46
47/* iMX50/53 have same addresses, but not iMX51 */
48#if defined(CONFIG_SOC_IMX50) || defined(CONFIG_SOC_IMX53)
49#ifdef UART_PADDR
50#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
51#endif
52#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
53#endif 29#endif
54 30
55#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 842fbcb0d6c..9fe0dfcf4e7 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 eba3118adfb..a599f01f8b9 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 00e812bbd81..fd9efb04465 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 00000000000..254a561a279
--- /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__ */
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index b3e10659e4b..49b14b1a7ab 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -367,4 +367,11 @@ config SAMSUNG_PD
367 help 367 help
368 Say Y here if you want to control Power Domain by Runtime PM. 368 Say Y here if you want to control Power Domain by Runtime PM.
369 369
370config DEBUG_S3C_UART
371 depends on PLAT_SAMSUNG
372 int
373 default "0" if DEBUG_S3C_UART0
374 default "1" if DEBUG_S3C_UART1
375 default "2" if DEBUG_S3C_UART2
376
370endif 377endif