aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig7
-rw-r--r--arch/arm/Kconfig.debug2
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/dts/Makefile6
-rw-r--r--arch/arm/boot/dts/qcom-msm8660-surf.dts59
-rw-r--r--arch/arm/boot/dts/qcom-msm8660.dtsi63
-rw-r--r--arch/arm/boot/dts/qcom-msm8960-cdp.dts66
-rw-r--r--arch/arm/boot/dts/qcom-msm8960.dtsi70
-rw-r--r--arch/arm/include/asm/smp.h9
-rw-r--r--arch/arm/kernel/devtree.c40
-rw-r--r--arch/arm/mach-msm/Kconfig54
-rw-r--r--arch/arm/mach-msm/Makefile8
-rw-r--r--arch/arm/mach-msm/common.h3
-rw-r--r--arch/arm/mach-msm/headsmp.S39
-rw-r--r--arch/arm/mach-msm/hotplug.c74
-rw-r--r--arch/arm/mach-msm/platsmp.c161
-rw-r--r--arch/arm/mach-msm/timer.c333
-rw-r--r--arch/arm/mach-qcom/Kconfig33
-rw-r--r--arch/arm/mach-qcom/Makefile5
-rw-r--r--arch/arm/mach-qcom/board.c (renamed from arch/arm/mach-msm/board-dt.c)23
-rw-r--r--arch/arm/mach-qcom/platsmp.c378
-rw-r--r--arch/arm/mach-qcom/scm-boot.c (renamed from arch/arm/mach-msm/scm-boot.c)0
-rw-r--r--arch/arm/mach-qcom/scm-boot.h (renamed from arch/arm/mach-msm/scm-boot.h)8
-rw-r--r--arch/arm/mach-qcom/scm.c (renamed from arch/arm/mach-msm/scm.c)0
-rw-r--r--arch/arm/mach-qcom/scm.h (renamed from arch/arm/mach-msm/scm.h)0
25 files changed, 623 insertions, 819 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e25419817791..f093f2030c1c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -657,9 +657,8 @@ config ARCH_PXA
657 help 657 help
658 Support for Intel/Marvell's PXA2xx/PXA3xx processor line. 658 Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
659 659
660config ARCH_MSM_NODT 660config ARCH_MSM
661 bool "Qualcomm MSM" 661 bool "Qualcomm MSM (non-multiplatform)"
662 select ARCH_MSM
663 select ARCH_REQUIRE_GPIOLIB 662 select ARCH_REQUIRE_GPIOLIB
664 select COMMON_CLK 663 select COMMON_CLK
665 select GENERIC_CLOCKEVENTS 664 select GENERIC_CLOCKEVENTS
@@ -1005,6 +1004,8 @@ source "arch/arm/plat-pxa/Kconfig"
1005 1004
1006source "arch/arm/mach-mmp/Kconfig" 1005source "arch/arm/mach-mmp/Kconfig"
1007 1006
1007source "arch/arm/mach-qcom/Kconfig"
1008
1008source "arch/arm/mach-realview/Kconfig" 1009source "arch/arm/mach-realview/Kconfig"
1009 1010
1010source "arch/arm/mach-rockchip/Kconfig" 1011source "arch/arm/mach-rockchip/Kconfig"
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 0531da8e5216..4491c7b05275 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -956,7 +956,7 @@ config DEBUG_STI_UART
956 956
957config DEBUG_MSM_UART 957config DEBUG_MSM_UART
958 bool 958 bool
959 depends on ARCH_MSM 959 depends on ARCH_MSM || ARCH_QCOM
960 960
961config DEBUG_LL_INCLUDE 961config DEBUG_LL_INCLUDE
962 string 962 string
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 08a9ef58d9c3..51e5bede657f 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -180,6 +180,7 @@ machine-$(CONFIG_ARCH_OMAP2PLUS) += omap2
180machine-$(CONFIG_ARCH_ORION5X) += orion5x 180machine-$(CONFIG_ARCH_ORION5X) += orion5x
181machine-$(CONFIG_ARCH_PICOXCELL) += picoxcell 181machine-$(CONFIG_ARCH_PICOXCELL) += picoxcell
182machine-$(CONFIG_ARCH_PXA) += pxa 182machine-$(CONFIG_ARCH_PXA) += pxa
183machine-$(CONFIG_ARCH_QCOM) += qcom
183machine-$(CONFIG_ARCH_REALVIEW) += realview 184machine-$(CONFIG_ARCH_REALVIEW) += realview
184machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip 185machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip
185machine-$(CONFIG_ARCH_RPC) += rpc 186machine-$(CONFIG_ARCH_RPC) += rpc
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 6d1e43d46187..3269029a1ce6 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -119,9 +119,6 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \
119 kirkwood-ts219-6282.dtb 119 kirkwood-ts219-6282.dtb
120dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb 120dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
121dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb 121dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
122dtb-$(CONFIG_ARCH_MSM) += qcom-msm8660-surf.dtb \
123 qcom-msm8960-cdp.dtb \
124 qcom-apq8074-dragonboard.dtb
125dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ 122dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
126 armada-370-mirabox.dtb \ 123 armada-370-mirabox.dtb \
127 armada-370-netgear-rn102.dtb \ 124 armada-370-netgear-rn102.dtb \
@@ -233,6 +230,9 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
233 dra7-evm.dtb 230 dra7-evm.dtb
234dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb 231dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
235dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb 232dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
233dtb-$(CONFIG_ARCH_QCOM) += qcom-msm8660-surf.dtb \
234 qcom-msm8960-cdp.dtb \
235 qcom-apq8074-dragonboard.dtb
236dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \ 236dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
237 ste-hrefprev60-stuib.dtb \ 237 ste-hrefprev60-stuib.dtb \
238 ste-hrefprev60-tvk.dtb \ 238 ste-hrefprev60-tvk.dtb \
diff --git a/arch/arm/boot/dts/qcom-msm8660-surf.dts b/arch/arm/boot/dts/qcom-msm8660-surf.dts
index 68a72f5507b9..169bad90dac9 100644
--- a/arch/arm/boot/dts/qcom-msm8660-surf.dts
+++ b/arch/arm/boot/dts/qcom-msm8660-surf.dts
@@ -1,63 +1,6 @@
1/dts-v1/; 1#include "qcom-msm8660.dtsi"
2
3/include/ "skeleton.dtsi"
4
5#include <dt-bindings/clock/qcom,gcc-msm8660.h>
6 2
7/ { 3/ {
8 model = "Qualcomm MSM8660 SURF"; 4 model = "Qualcomm MSM8660 SURF";
9 compatible = "qcom,msm8660-surf", "qcom,msm8660"; 5 compatible = "qcom,msm8660-surf", "qcom,msm8660";
10 interrupt-parent = <&intc>;
11
12 intc: interrupt-controller@2080000 {
13 compatible = "qcom,msm-8660-qgic";
14 interrupt-controller;
15 #interrupt-cells = <3>;
16 reg = < 0x02080000 0x1000 >,
17 < 0x02081000 0x1000 >;
18 };
19
20 timer@2000000 {
21 compatible = "qcom,scss-timer", "qcom,msm-timer";
22 interrupts = <1 0 0x301>,
23 <1 1 0x301>,
24 <1 2 0x301>;
25 reg = <0x02000000 0x100>;
26 clock-frequency = <27000000>,
27 <32768>;
28 cpu-offset = <0x40000>;
29 };
30
31 msmgpio: gpio@800000 {
32 compatible = "qcom,msm-gpio";
33 reg = <0x00800000 0x4000>;
34 gpio-controller;
35 #gpio-cells = <2>;
36 ngpio = <173>;
37 interrupts = <0 16 0x4>;
38 interrupt-controller;
39 #interrupt-cells = <2>;
40 };
41
42 gcc: clock-controller@900000 {
43 compatible = "qcom,gcc-msm8660";
44 #clock-cells = <1>;
45 #reset-cells = <1>;
46 reg = <0x900000 0x4000>;
47 };
48
49 serial@19c40000 {
50 compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
51 reg = <0x19c40000 0x1000>,
52 <0x19c00000 0x1000>;
53 interrupts = <0 195 0x0>;
54 clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
55 clock-names = "core", "iface";
56 };
57
58 qcom,ssbi@500000 {
59 compatible = "qcom,ssbi";
60 reg = <0x500000 0x1000>;
61 qcom,controller-type = "pmic-arbiter";
62 };
63}; 6};
diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi
new file mode 100644
index 000000000000..69d6c4edea30
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-msm8660.dtsi
@@ -0,0 +1,63 @@
1/dts-v1/;
2
3/include/ "skeleton.dtsi"
4
5#include <dt-bindings/clock/qcom,gcc-msm8660.h>
6
7/ {
8 model = "Qualcomm MSM8660";
9 compatible = "qcom,msm8660";
10 interrupt-parent = <&intc>;
11
12 intc: interrupt-controller@2080000 {
13 compatible = "qcom,msm-8660-qgic";
14 interrupt-controller;
15 #interrupt-cells = <3>;
16 reg = < 0x02080000 0x1000 >,
17 < 0x02081000 0x1000 >;
18 };
19
20 timer@2000000 {
21 compatible = "qcom,scss-timer", "qcom,msm-timer";
22 interrupts = <1 0 0x301>,
23 <1 1 0x301>,
24 <1 2 0x301>;
25 reg = <0x02000000 0x100>;
26 clock-frequency = <27000000>,
27 <32768>;
28 cpu-offset = <0x40000>;
29 };
30
31 msmgpio: gpio@800000 {
32 compatible = "qcom,msm-gpio";
33 reg = <0x00800000 0x4000>;
34 gpio-controller;
35 #gpio-cells = <2>;
36 ngpio = <173>;
37 interrupts = <0 16 0x4>;
38 interrupt-controller;
39 #interrupt-cells = <2>;
40 };
41
42 gcc: clock-controller@900000 {
43 compatible = "qcom,gcc-msm8660";
44 #clock-cells = <1>;
45 #reset-cells = <1>;
46 reg = <0x900000 0x4000>;
47 };
48
49 serial@19c40000 {
50 compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
51 reg = <0x19c40000 0x1000>,
52 <0x19c00000 0x1000>;
53 interrupts = <0 195 0x0>;
54 clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
55 clock-names = "core", "iface";
56 };
57
58 qcom,ssbi@500000 {
59 compatible = "qcom,ssbi";
60 reg = <0x500000 0x1000>;
61 qcom,controller-type = "pmic-arbiter";
62 };
63};
diff --git a/arch/arm/boot/dts/qcom-msm8960-cdp.dts b/arch/arm/boot/dts/qcom-msm8960-cdp.dts
index 7c30de4fa302..a58fb88315f6 100644
--- a/arch/arm/boot/dts/qcom-msm8960-cdp.dts
+++ b/arch/arm/boot/dts/qcom-msm8960-cdp.dts
@@ -1,70 +1,6 @@
1/dts-v1/; 1#include "qcom-msm8960.dtsi"
2
3/include/ "skeleton.dtsi"
4
5#include <dt-bindings/clock/qcom,gcc-msm8960.h>
6 2
7/ { 3/ {
8 model = "Qualcomm MSM8960 CDP"; 4 model = "Qualcomm MSM8960 CDP";
9 compatible = "qcom,msm8960-cdp", "qcom,msm8960"; 5 compatible = "qcom,msm8960-cdp", "qcom,msm8960";
10 interrupt-parent = <&intc>;
11
12 intc: interrupt-controller@2000000 {
13 compatible = "qcom,msm-qgic2";
14 interrupt-controller;
15 #interrupt-cells = <3>;
16 reg = < 0x02000000 0x1000 >,
17 < 0x02002000 0x1000 >;
18 };
19
20 timer@200a000 {
21 compatible = "qcom,kpss-timer", "qcom,msm-timer";
22 interrupts = <1 1 0x301>,
23 <1 2 0x301>,
24 <1 3 0x301>;
25 reg = <0x0200a000 0x100>;
26 clock-frequency = <27000000>,
27 <32768>;
28 cpu-offset = <0x80000>;
29 };
30
31 msmgpio: gpio@800000 {
32 compatible = "qcom,msm-gpio";
33 gpio-controller;
34 #gpio-cells = <2>;
35 ngpio = <150>;
36 interrupts = <0 16 0x4>;
37 interrupt-controller;
38 #interrupt-cells = <2>;
39 reg = <0x800000 0x4000>;
40 };
41
42 gcc: clock-controller@900000 {
43 compatible = "qcom,gcc-msm8960";
44 #clock-cells = <1>;
45 #reset-cells = <1>;
46 reg = <0x900000 0x4000>;
47 };
48
49 clock-controller@4000000 {
50 compatible = "qcom,mmcc-msm8960";
51 reg = <0x4000000 0x1000>;
52 #clock-cells = <1>;
53 #reset-cells = <1>;
54 };
55
56 serial@16440000 {
57 compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
58 reg = <0x16440000 0x1000>,
59 <0x16400000 0x1000>;
60 interrupts = <0 154 0x0>;
61 clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
62 clock-names = "core", "iface";
63 };
64
65 qcom,ssbi@500000 {
66 compatible = "qcom,ssbi";
67 reg = <0x500000 0x1000>;
68 qcom,controller-type = "pmic-arbiter";
69 };
70}; 6};
diff --git a/arch/arm/boot/dts/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom-msm8960.dtsi
new file mode 100644
index 000000000000..ff002826552a
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
@@ -0,0 +1,70 @@
1/dts-v1/;
2
3/include/ "skeleton.dtsi"
4
5#include <dt-bindings/clock/qcom,gcc-msm8960.h>
6
7/ {
8 model = "Qualcomm MSM8960";
9 compatible = "qcom,msm8960";
10 interrupt-parent = <&intc>;
11
12 intc: interrupt-controller@2000000 {
13 compatible = "qcom,msm-qgic2";
14 interrupt-controller;
15 #interrupt-cells = <3>;
16 reg = < 0x02000000 0x1000 >,
17 < 0x02002000 0x1000 >;
18 };
19
20 timer@200a000 {
21 compatible = "qcom,kpss-timer", "qcom,msm-timer";
22 interrupts = <1 1 0x301>,
23 <1 2 0x301>,
24 <1 3 0x301>;
25 reg = <0x0200a000 0x100>;
26 clock-frequency = <27000000>,
27 <32768>;
28 cpu-offset = <0x80000>;
29 };
30
31 msmgpio: gpio@800000 {
32 compatible = "qcom,msm-gpio";
33 gpio-controller;
34 #gpio-cells = <2>;
35 ngpio = <150>;
36 interrupts = <0 16 0x4>;
37 interrupt-controller;
38 #interrupt-cells = <2>;
39 reg = <0x800000 0x4000>;
40 };
41
42 gcc: clock-controller@900000 {
43 compatible = "qcom,gcc-msm8960";
44 #clock-cells = <1>;
45 #reset-cells = <1>;
46 reg = <0x900000 0x4000>;
47 };
48
49 clock-controller@4000000 {
50 compatible = "qcom,mmcc-msm8960";
51 reg = <0x4000000 0x1000>;
52 #clock-cells = <1>;
53 #reset-cells = <1>;
54 };
55
56 serial@16440000 {
57 compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
58 reg = <0x16440000 0x1000>,
59 <0x16400000 0x1000>;
60 interrupts = <0 154 0x0>;
61 clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
62 clock-names = "core", "iface";
63 };
64
65 qcom,ssbi@500000 {
66 compatible = "qcom,ssbi";
67 reg = <0x500000 0x1000>;
68 qcom,controller-type = "pmic-arbiter";
69 };
70};
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 22a3b9b5d4a1..772435b08207 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -114,6 +114,15 @@ struct smp_operations {
114#endif 114#endif
115}; 115};
116 116
117struct of_cpu_method {
118 const char *method;
119 struct smp_operations *ops;
120};
121
122#define CPU_METHOD_OF_DECLARE(name, _method, _ops) \
123 static const struct of_cpu_method __cpu_method_of_table_##name \
124 __used __section(__cpu_method_of_table) \
125 = { .method = _method, .ops = _ops }
117/* 126/*
118 * set platform specific SMP operations 127 * set platform specific SMP operations
119 */ 128 */
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
index f751714d52c1..c7419a585ddc 100644
--- a/arch/arm/kernel/devtree.c
+++ b/arch/arm/kernel/devtree.c
@@ -18,6 +18,7 @@
18#include <linux/of_fdt.h> 18#include <linux/of_fdt.h>
19#include <linux/of_irq.h> 19#include <linux/of_irq.h>
20#include <linux/of_platform.h> 20#include <linux/of_platform.h>
21#include <linux/smp.h>
21 22
22#include <asm/cputype.h> 23#include <asm/cputype.h>
23#include <asm/setup.h> 24#include <asm/setup.h>
@@ -63,6 +64,34 @@ void __init arm_dt_memblock_reserve(void)
63 } 64 }
64} 65}
65 66
67#ifdef CONFIG_SMP
68extern struct of_cpu_method __cpu_method_of_table_begin[];
69extern struct of_cpu_method __cpu_method_of_table_end[];
70
71static int __init set_smp_ops_by_method(struct device_node *node)
72{
73 const char *method;
74 struct of_cpu_method *m = __cpu_method_of_table_begin;
75
76 if (of_property_read_string(node, "enable-method", &method))
77 return 0;
78
79 for (; m < __cpu_method_of_table_end; m++)
80 if (!strcmp(m->method, method)) {
81 smp_set_ops(m->ops);
82 return 1;
83 }
84
85 return 0;
86}
87#else
88static inline int set_smp_ops_by_method(struct device_node *node)
89{
90 return 1;
91}
92#endif
93
94
66/* 95/*
67 * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree 96 * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree
68 * and builds the cpu logical map array containing MPIDR values related to 97 * and builds the cpu logical map array containing MPIDR values related to
@@ -79,6 +108,7 @@ void __init arm_dt_init_cpu_maps(void)
79 * read as 0. 108 * read as 0.
80 */ 109 */
81 struct device_node *cpu, *cpus; 110 struct device_node *cpu, *cpus;
111 int found_method = 0;
82 u32 i, j, cpuidx = 1; 112 u32 i, j, cpuidx = 1;
83 u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0; 113 u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
84 114
@@ -150,8 +180,18 @@ void __init arm_dt_init_cpu_maps(void)
150 } 180 }
151 181
152 tmp_map[i] = hwid; 182 tmp_map[i] = hwid;
183
184 if (!found_method)
185 found_method = set_smp_ops_by_method(cpu);
153 } 186 }
154 187
188 /*
189 * Fallback to an enable-method in the cpus node if nothing found in
190 * a cpu node.
191 */
192 if (!found_method)
193 set_smp_ops_by_method(cpus);
194
155 if (!bootcpu_valid) { 195 if (!bootcpu_valid) {
156 pr_warn("DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map\n"); 196 pr_warn("DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map\n");
157 return; 197 return;
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 9625cf378931..a7f959e58c3d 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1,50 +1,9 @@
1config ARCH_MSM
2 bool
3
4config ARCH_MSM_DT
5 bool "Qualcomm MSM DT Support" if ARCH_MULTI_V7
6 select ARCH_MSM
7 select ARCH_REQUIRE_GPIOLIB
8 select CLKSRC_OF
9 select GENERIC_CLOCKEVENTS
10 help
11 Support for Qualcomm's devicetree based MSM systems.
12
13if ARCH_MSM 1if ARCH_MSM
14 2
15menu "Qualcomm MSM SoC Selection"
16 depends on ARCH_MSM_DT
17
18config ARCH_MSM8X60
19 bool "Enable support for MSM8X60"
20 select ARM_GIC
21 select CPU_V7
22 select HAVE_SMP
23 select MSM_SCM if SMP
24 select MSM_TIMER
25
26config ARCH_MSM8960
27 bool "Enable support for MSM8960"
28 select ARM_GIC
29 select CPU_V7
30 select HAVE_SMP
31 select MSM_SCM if SMP
32 select MSM_TIMER
33
34config ARCH_MSM8974
35 bool "Enable support for MSM8974"
36 select ARM_GIC
37 select CPU_V7
38 select HAVE_ARM_ARCH_TIMER
39 select HAVE_SMP
40 select MSM_SCM if SMP
41
42endmenu
43
44choice 3choice
45 prompt "Qualcomm MSM SoC Type" 4 prompt "Qualcomm MSM SoC Type"
46 default ARCH_MSM7X00A 5 default ARCH_MSM7X00A
47 depends on ARCH_MSM_NODT 6 depends on ARCH_MSM
48 7
49config ARCH_MSM7X00A 8config ARCH_MSM7X00A
50 bool "MSM7x00A / MSM7x01A" 9 bool "MSM7x00A / MSM7x01A"
@@ -54,7 +13,7 @@ config ARCH_MSM7X00A
54 select MACH_TROUT if !MACH_HALIBUT 13 select MACH_TROUT if !MACH_HALIBUT
55 select MSM_PROC_COMM 14 select MSM_PROC_COMM
56 select MSM_SMD 15 select MSM_SMD
57 select MSM_TIMER 16 select CLKSRC_QCOM
58 select MSM_SMD_PKG3 17 select MSM_SMD_PKG3
59 18
60config ARCH_MSM7X30 19config ARCH_MSM7X30
@@ -66,7 +25,7 @@ config ARCH_MSM7X30
66 select MSM_GPIOMUX 25 select MSM_GPIOMUX
67 select MSM_PROC_COMM 26 select MSM_PROC_COMM
68 select MSM_SMD 27 select MSM_SMD
69 select MSM_TIMER 28 select CLKSRC_QCOM
70 select MSM_VIC 29 select MSM_VIC
71 30
72config ARCH_QSD8X50 31config ARCH_QSD8X50
@@ -78,7 +37,7 @@ config ARCH_QSD8X50
78 select MSM_GPIOMUX 37 select MSM_GPIOMUX
79 select MSM_PROC_COMM 38 select MSM_PROC_COMM
80 select MSM_SMD 39 select MSM_SMD
81 select MSM_TIMER 40 select CLKSRC_QCOM
82 select MSM_VIC 41 select MSM_VIC
83 42
84endchoice 43endchoice
@@ -99,7 +58,7 @@ config MSM_VIC
99 bool 58 bool
100 59
101menu "Qualcomm MSM Board Type" 60menu "Qualcomm MSM Board Type"
102 depends on ARCH_MSM_NODT 61 depends on ARCH_MSM
103 62
104config MACH_HALIBUT 63config MACH_HALIBUT
105 depends on ARCH_MSM 64 depends on ARCH_MSM
@@ -153,7 +112,4 @@ config MSM_GPIOMUX
153config MSM_SCM 112config MSM_SCM
154 bool 113 bool
155 114
156config MSM_TIMER
157 bool
158
159endif 115endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 8e307a10d3c3..27c078a568df 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -1,4 +1,3 @@
1obj-$(CONFIG_MSM_TIMER) += timer.o
2obj-$(CONFIG_MSM_PROC_COMM) += clock.o 1obj-$(CONFIG_MSM_PROC_COMM) += clock.o
3 2
4obj-$(CONFIG_MSM_VIC) += irq-vic.o 3obj-$(CONFIG_MSM_VIC) += irq-vic.o
@@ -14,18 +13,11 @@ obj-$(CONFIG_ARCH_QSD8X50) += dma.o io.o
14 13
15obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o 14obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
16obj-$(CONFIG_MSM_SMD) += last_radio_log.o 15obj-$(CONFIG_MSM_SMD) += last_radio_log.o
17obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
18
19CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
20
21obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
22obj-$(CONFIG_SMP) += headsmp.o platsmp.o
23 16
24obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o 17obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
25obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o 18obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o
26obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o 19obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
27obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o 20obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
28obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o 21obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
29obj-$(CONFIG_ARCH_MSM_DT) += board-dt.o
30obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o 22obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o
31obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o 23obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o
diff --git a/arch/arm/mach-msm/common.h b/arch/arm/mach-msm/common.h
index 33c7725adae2..572479a3c7be 100644
--- a/arch/arm/mach-msm/common.h
+++ b/arch/arm/mach-msm/common.h
@@ -23,9 +23,6 @@ extern void msm_map_qsd8x50_io(void);
23extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size, 23extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size,
24 unsigned int mtype, void *caller); 24 unsigned int mtype, void *caller);
25 25
26extern struct smp_operations msm_smp_ops;
27extern void msm_cpu_die(unsigned int cpu);
28
29struct msm_mmc_platform_data; 26struct msm_mmc_platform_data;
30 27
31extern void msm_add_devices(void); 28extern void msm_add_devices(void);
diff --git a/arch/arm/mach-msm/headsmp.S b/arch/arm/mach-msm/headsmp.S
deleted file mode 100644
index 6c62c3f82fe6..000000000000
--- a/arch/arm/mach-msm/headsmp.S
+++ /dev/null
@@ -1,39 +0,0 @@
1/*
2 * linux/arch/arm/mach-realview/headsmp.S
3 *
4 * Copyright (c) 2003 ARM Limited
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/linkage.h>
12#include <linux/init.h>
13
14/*
15 * MSM specific entry point for secondary CPUs. This provides
16 * a "holding pen" into which all secondary cores are held until we're
17 * ready for them to initialise.
18 */
19ENTRY(msm_secondary_startup)
20 mrc p15, 0, r0, c0, c0, 5
21 and r0, r0, #15
22 adr r4, 1f
23 ldmia r4, {r5, r6}
24 sub r4, r4, r5
25 add r6, r6, r4
26pen: ldr r7, [r6]
27 cmp r7, r0
28 bne pen
29
30 /*
31 * we've been released from the holding pen: secondary_stack
32 * should now contain the SVC stack for this core
33 */
34 b secondary_startup
35ENDPROC(msm_secondary_startup)
36
37 .align
381: .long .
39 .long pen_release
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
deleted file mode 100644
index 326a87261f9a..000000000000
--- a/arch/arm/mach-msm/hotplug.c
+++ /dev/null
@@ -1,74 +0,0 @@
1/*
2 * Copyright (C) 2002 ARM Ltd.
3 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#include <linux/kernel.h>
10#include <linux/errno.h>
11#include <linux/smp.h>
12
13#include <asm/smp_plat.h>
14
15#include "common.h"
16
17static inline void cpu_enter_lowpower(void)
18{
19}
20
21static inline void cpu_leave_lowpower(void)
22{
23}
24
25static inline void platform_do_lowpower(unsigned int cpu)
26{
27 /* Just enter wfi for now. TODO: Properly shut off the cpu. */
28 for (;;) {
29 /*
30 * here's the WFI
31 */
32 asm("wfi"
33 :
34 :
35 : "memory", "cc");
36
37 if (pen_release == cpu_logical_map(cpu)) {
38 /*
39 * OK, proper wakeup, we're done
40 */
41 break;
42 }
43
44 /*
45 * getting here, means that we have come out of WFI without
46 * having been woken up - this shouldn't happen
47 *
48 * The trouble is, letting people know about this is not really
49 * possible, since we are currently running incoherently, and
50 * therefore cannot safely call printk() or anything else
51 */
52 pr_debug("CPU%u: spurious wakeup call\n", cpu);
53 }
54}
55
56/*
57 * platform-specific code to shutdown a CPU
58 *
59 * Called with IRQs disabled
60 */
61void __ref msm_cpu_die(unsigned int cpu)
62{
63 /*
64 * we're ready for shutdown now, so do it
65 */
66 cpu_enter_lowpower();
67 platform_do_lowpower(cpu);
68
69 /*
70 * bring this CPU back into the world of cache
71 * coherency, and then restore interrupts
72 */
73 cpu_leave_lowpower();
74}
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
deleted file mode 100644
index f10a1f58fde9..000000000000
--- a/arch/arm/mach-msm/platsmp.c
+++ /dev/null
@@ -1,161 +0,0 @@
1/*
2 * Copyright (C) 2002 ARM Ltd.
3 * All Rights Reserved
4 * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/init.h>
12#include <linux/errno.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/jiffies.h>
16#include <linux/smp.h>
17#include <linux/io.h>
18
19#include <asm/cacheflush.h>
20#include <asm/cputype.h>
21#include <asm/mach-types.h>
22#include <asm/smp_plat.h>
23
24#include "scm-boot.h"
25#include "common.h"
26
27#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
28#define SCSS_CPU1CORE_RESET 0xD80
29#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
30
31extern void msm_secondary_startup(void);
32
33static DEFINE_SPINLOCK(boot_lock);
34
35static inline int get_core_count(void)
36{
37 /* 1 + the PART[1:0] field of MIDR */
38 return ((read_cpuid_id() >> 4) & 3) + 1;
39}
40
41static void msm_secondary_init(unsigned int cpu)
42{
43 /*
44 * let the primary processor know we're out of the
45 * pen, then head off into the C entry point
46 */
47 pen_release = -1;
48 smp_wmb();
49
50 /*
51 * Synchronise with the boot thread.
52 */
53 spin_lock(&boot_lock);
54 spin_unlock(&boot_lock);
55}
56
57static void prepare_cold_cpu(unsigned int cpu)
58{
59 int ret;
60 ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup),
61 SCM_FLAG_COLDBOOT_CPU1);
62 if (ret == 0) {
63 void __iomem *sc1_base_ptr;
64 sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
65 if (sc1_base_ptr) {
66 writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
67 writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
68 writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
69 iounmap(sc1_base_ptr);
70 }
71 } else
72 printk(KERN_DEBUG "Failed to set secondary core boot "
73 "address\n");
74}
75
76static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
77{
78 unsigned long timeout;
79 static int cold_boot_done;
80
81 /* Only need to bring cpu out of reset this way once */
82 if (cold_boot_done == false) {
83 prepare_cold_cpu(cpu);
84 cold_boot_done = true;
85 }
86
87 /*
88 * set synchronisation state between this boot processor
89 * and the secondary one
90 */
91 spin_lock(&boot_lock);
92
93 /*
94 * The secondary processor is waiting to be released from
95 * the holding pen - release it, then wait for it to flag
96 * that it has been released by resetting pen_release.
97 *
98 * Note that "pen_release" is the hardware CPU ID, whereas
99 * "cpu" is Linux's internal ID.
100 */
101 pen_release = cpu_logical_map(cpu);
102 sync_cache_w(&pen_release);
103
104 /*
105 * Send the secondary CPU a soft interrupt, thereby causing
106 * the boot monitor to read the system wide flags register,
107 * and branch to the address found there.
108 */
109 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
110
111 timeout = jiffies + (1 * HZ);
112 while (time_before(jiffies, timeout)) {
113 smp_rmb();
114 if (pen_release == -1)
115 break;
116
117 udelay(10);
118 }
119
120 /*
121 * now the secondary core is starting up let it run its
122 * calibrations, then wait for it to finish
123 */
124 spin_unlock(&boot_lock);
125
126 return pen_release != -1 ? -ENOSYS : 0;
127}
128
129/*
130 * Initialise the CPU possible map early - this describes the CPUs
131 * which may be present or become present in the system. The msm8x60
132 * does not support the ARM SCU, so just set the possible cpu mask to
133 * NR_CPUS.
134 */
135static void __init msm_smp_init_cpus(void)
136{
137 unsigned int i, ncores = get_core_count();
138
139 if (ncores > nr_cpu_ids) {
140 pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
141 ncores, nr_cpu_ids);
142 ncores = nr_cpu_ids;
143 }
144
145 for (i = 0; i < ncores; i++)
146 set_cpu_possible(i, true);
147}
148
149static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
150{
151}
152
153struct smp_operations msm_smp_ops __initdata = {
154 .smp_init_cpus = msm_smp_init_cpus,
155 .smp_prepare_cpus = msm_smp_prepare_cpus,
156 .smp_secondary_init = msm_secondary_init,
157 .smp_boot_secondary = msm_boot_secondary,
158#ifdef CONFIG_HOTPLUG_CPU
159 .cpu_die = msm_cpu_die,
160#endif
161};
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
deleted file mode 100644
index fd1644987534..000000000000
--- a/arch/arm/mach-msm/timer.c
+++ /dev/null
@@ -1,333 +0,0 @@
1/*
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/clocksource.h>
18#include <linux/clockchips.h>
19#include <linux/cpu.h>
20#include <linux/init.h>
21#include <linux/interrupt.h>
22#include <linux/irq.h>
23#include <linux/io.h>
24#include <linux/of.h>
25#include <linux/of_address.h>
26#include <linux/of_irq.h>
27#include <linux/sched_clock.h>
28
29#include <asm/mach/time.h>
30
31#include "common.h"
32
33#define TIMER_MATCH_VAL 0x0000
34#define TIMER_COUNT_VAL 0x0004
35#define TIMER_ENABLE 0x0008
36#define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1)
37#define TIMER_ENABLE_EN BIT(0)
38#define TIMER_CLEAR 0x000C
39#define DGT_CLK_CTL 0x10
40#define DGT_CLK_CTL_DIV_4 0x3
41#define TIMER_STS_GPT0_CLR_PEND BIT(10)
42
43#define GPT_HZ 32768
44
45#define MSM_DGT_SHIFT 5
46
47static void __iomem *event_base;
48static void __iomem *sts_base;
49
50static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
51{
52 struct clock_event_device *evt = dev_id;
53 /* Stop the timer tick */
54 if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
55 u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
56 ctrl &= ~TIMER_ENABLE_EN;
57 writel_relaxed(ctrl, event_base + TIMER_ENABLE);
58 }
59 evt->event_handler(evt);
60 return IRQ_HANDLED;
61}
62
63static int msm_timer_set_next_event(unsigned long cycles,
64 struct clock_event_device *evt)
65{
66 u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
67
68 ctrl &= ~TIMER_ENABLE_EN;
69 writel_relaxed(ctrl, event_base + TIMER_ENABLE);
70
71 writel_relaxed(ctrl, event_base + TIMER_CLEAR);
72 writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
73
74 if (sts_base)
75 while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND)
76 cpu_relax();
77
78 writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
79 return 0;
80}
81
82static void msm_timer_set_mode(enum clock_event_mode mode,
83 struct clock_event_device *evt)
84{
85 u32 ctrl;
86
87 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
88 ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN);
89
90 switch (mode) {
91 case CLOCK_EVT_MODE_RESUME:
92 case CLOCK_EVT_MODE_PERIODIC:
93 break;
94 case CLOCK_EVT_MODE_ONESHOT:
95 /* Timer is enabled in set_next_event */
96 break;
97 case CLOCK_EVT_MODE_UNUSED:
98 case CLOCK_EVT_MODE_SHUTDOWN:
99 break;
100 }
101 writel_relaxed(ctrl, event_base + TIMER_ENABLE);
102}
103
104static struct clock_event_device __percpu *msm_evt;
105
106static void __iomem *source_base;
107
108static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
109{
110 return readl_relaxed(source_base + TIMER_COUNT_VAL);
111}
112
113static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
114{
115 /*
116 * Shift timer count down by a constant due to unreliable lower bits
117 * on some targets.
118 */
119 return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
120}
121
122static struct clocksource msm_clocksource = {
123 .name = "dg_timer",
124 .rating = 300,
125 .read = msm_read_timer_count,
126 .mask = CLOCKSOURCE_MASK(32),
127 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
128};
129
130static int msm_timer_irq;
131static int msm_timer_has_ppi;
132
133static int msm_local_timer_setup(struct clock_event_device *evt)
134{
135 int cpu = smp_processor_id();
136 int err;
137
138 evt->irq = msm_timer_irq;
139 evt->name = "msm_timer";
140 evt->features = CLOCK_EVT_FEAT_ONESHOT;
141 evt->rating = 200;
142 evt->set_mode = msm_timer_set_mode;
143 evt->set_next_event = msm_timer_set_next_event;
144 evt->cpumask = cpumask_of(cpu);
145
146 clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
147
148 if (msm_timer_has_ppi) {
149 enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
150 } else {
151 err = request_irq(evt->irq, msm_timer_interrupt,
152 IRQF_TIMER | IRQF_NOBALANCING |
153 IRQF_TRIGGER_RISING, "gp_timer", evt);
154 if (err)
155 pr_err("request_irq failed\n");
156 }
157
158 return 0;
159}
160
161static void msm_local_timer_stop(struct clock_event_device *evt)
162{
163 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
164 disable_percpu_irq(evt->irq);
165}
166
167static int msm_timer_cpu_notify(struct notifier_block *self,
168 unsigned long action, void *hcpu)
169{
170 /*
171 * Grab cpu pointer in each case to avoid spurious
172 * preemptible warnings
173 */
174 switch (action & ~CPU_TASKS_FROZEN) {
175 case CPU_STARTING:
176 msm_local_timer_setup(this_cpu_ptr(msm_evt));
177 break;
178 case CPU_DYING:
179 msm_local_timer_stop(this_cpu_ptr(msm_evt));
180 break;
181 }
182
183 return NOTIFY_OK;
184}
185
186static struct notifier_block msm_timer_cpu_nb = {
187 .notifier_call = msm_timer_cpu_notify,
188};
189
190static u64 notrace msm_sched_clock_read(void)
191{
192 return msm_clocksource.read(&msm_clocksource);
193}
194
195static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
196 bool percpu)
197{
198 struct clocksource *cs = &msm_clocksource;
199 int res = 0;
200
201 msm_timer_irq = irq;
202 msm_timer_has_ppi = percpu;
203
204 msm_evt = alloc_percpu(struct clock_event_device);
205 if (!msm_evt) {
206 pr_err("memory allocation failed for clockevents\n");
207 goto err;
208 }
209
210 if (percpu)
211 res = request_percpu_irq(irq, msm_timer_interrupt,
212 "gp_timer", msm_evt);
213
214 if (res) {
215 pr_err("request_percpu_irq failed\n");
216 } else {
217 res = register_cpu_notifier(&msm_timer_cpu_nb);
218 if (res) {
219 free_percpu_irq(irq, msm_evt);
220 goto err;
221 }
222
223 /* Immediately configure the timer on the boot CPU */
224 msm_local_timer_setup(__this_cpu_ptr(msm_evt));
225 }
226
227err:
228 writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
229 res = clocksource_register_hz(cs, dgt_hz);
230 if (res)
231 pr_err("clocksource_register failed\n");
232 sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
233}
234
235#ifdef CONFIG_OF
236static void __init msm_dt_timer_init(struct device_node *np)
237{
238 u32 freq;
239 int irq;
240 struct resource res;
241 u32 percpu_offset;
242 void __iomem *base;
243 void __iomem *cpu0_base;
244
245 base = of_iomap(np, 0);
246 if (!base) {
247 pr_err("Failed to map event base\n");
248 return;
249 }
250
251 /* We use GPT0 for the clockevent */
252 irq = irq_of_parse_and_map(np, 1);
253 if (irq <= 0) {
254 pr_err("Can't get irq\n");
255 return;
256 }
257
258 /* We use CPU0's DGT for the clocksource */
259 if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
260 percpu_offset = 0;
261
262 if (of_address_to_resource(np, 0, &res)) {
263 pr_err("Failed to parse DGT resource\n");
264 return;
265 }
266
267 cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res));
268 if (!cpu0_base) {
269 pr_err("Failed to map source base\n");
270 return;
271 }
272
273 if (of_property_read_u32(np, "clock-frequency", &freq)) {
274 pr_err("Unknown frequency\n");
275 return;
276 }
277
278 event_base = base + 0x4;
279 sts_base = base + 0x88;
280 source_base = cpu0_base + 0x24;
281 freq /= 4;
282 writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
283
284 msm_timer_init(freq, 32, irq, !!percpu_offset);
285}
286CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
287CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
288#endif
289
290static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
291 u32 sts)
292{
293 void __iomem *base;
294
295 base = ioremap(addr, SZ_256);
296 if (!base) {
297 pr_err("Failed to map timer base\n");
298 return -ENOMEM;
299 }
300 event_base = base + event;
301 source_base = base + source;
302 if (sts)
303 sts_base = base + sts;
304
305 return 0;
306}
307
308void __init msm7x01_timer_init(void)
309{
310 struct clocksource *cs = &msm_clocksource;
311
312 if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0))
313 return;
314 cs->read = msm_read_timer_count_shift;
315 cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT));
316 /* 600 KHz */
317 msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7,
318 false);
319}
320
321void __init msm7x30_timer_init(void)
322{
323 if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80))
324 return;
325 msm_timer_init(24576000 / 4, 32, 1, false);
326}
327
328void __init qsd8x50_timer_init(void)
329{
330 if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34))
331 return;
332 msm_timer_init(19200000 / 4, 32, 7, false);
333}
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
new file mode 100644
index 000000000000..a028be234334
--- /dev/null
+++ b/arch/arm/mach-qcom/Kconfig
@@ -0,0 +1,33 @@
1config ARCH_QCOM
2 bool "Qualcomm Support" if ARCH_MULTI_V7
3 select ARCH_REQUIRE_GPIOLIB
4 select ARM_GIC
5 select CLKSRC_OF
6 select GENERIC_CLOCKEVENTS
7 select HAVE_SMP
8 select QCOM_SCM if SMP
9 help
10 Support for Qualcomm's devicetree based systems.
11
12if ARCH_QCOM
13
14menu "Qualcomm SoC Selection"
15
16config ARCH_MSM8X60
17 bool "Enable support for MSM8X60"
18 select CLKSRC_QCOM
19
20config ARCH_MSM8960
21 bool "Enable support for MSM8960"
22 select CLKSRC_QCOM
23
24config ARCH_MSM8974
25 bool "Enable support for MSM8974"
26 select HAVE_ARM_ARCH_TIMER
27
28endmenu
29
30config QCOM_SCM
31 bool
32
33endif
diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
new file mode 100644
index 000000000000..8f756ae1ae31
--- /dev/null
+++ b/arch/arm/mach-qcom/Makefile
@@ -0,0 +1,5 @@
1obj-y := board.o
2obj-$(CONFIG_SMP) += platsmp.o
3obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o
4
5CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-qcom/board.c
index 1f11d93e700e..bae617ef0b31 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-qcom/board.c
@@ -1,4 +1,4 @@
1/* Copyright (c) 2010-2012,2013 The Linux Foundation. All rights reserved. 1/* Copyright (c) 2010-2014 The Linux Foundation. All rights reserved.
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and 4 * it under the terms of the GNU General Public License version 2 and
@@ -11,31 +11,16 @@
11 */ 11 */
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/of.h>
15#include <linux/of_platform.h>
16 14
17#include <asm/mach/arch.h> 15#include <asm/mach/arch.h>
18#include <asm/mach/map.h>
19 16
20#include "common.h" 17static const char * const qcom_dt_match[] __initconst = {
21
22static const char * const msm_dt_match[] __initconst = {
23 "qcom,msm8660-fluid",
24 "qcom,msm8660-surf", 18 "qcom,msm8660-surf",
25 "qcom,msm8960-cdp", 19 "qcom,msm8960-cdp",
26 NULL
27};
28
29static const char * const apq8074_dt_match[] __initconst = {
30 "qcom,apq8074-dragonboard", 20 "qcom,apq8074-dragonboard",
31 NULL 21 NULL
32}; 22};
33 23
34DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)") 24DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
35 .smp = smp_ops(msm_smp_ops), 25 .dt_compat = qcom_dt_match,
36 .dt_compat = msm_dt_match,
37MACHINE_END
38
39DT_MACHINE_START(APQ_DT, "Qualcomm MSM (Flattened Device Tree)")
40 .dt_compat = apq8074_dt_match,
41MACHINE_END 26MACHINE_END
diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
new file mode 100644
index 000000000000..d6908569ecaf
--- /dev/null
+++ b/arch/arm/mach-qcom/platsmp.c
@@ -0,0 +1,378 @@
1/*
2 * Copyright (C) 2002 ARM Ltd.
3 * All Rights Reserved
4 * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
5 * Copyright (c) 2014 The Linux Foundation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/init.h>
13#include <linux/errno.h>
14#include <linux/delay.h>
15#include <linux/device.h>
16#include <linux/of.h>
17#include <linux/of_address.h>
18#include <linux/smp.h>
19#include <linux/io.h>
20
21#include <asm/smp_plat.h>
22
23#include "scm-boot.h"
24
25#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x35a0
26#define SCSS_CPU1CORE_RESET 0x2d80
27#define SCSS_DBG_STATUS_CORE_PWRDUP 0x2e64
28
29#define APCS_CPU_PWR_CTL 0x04
30#define PLL_CLAMP BIT(8)
31#define CORE_PWRD_UP BIT(7)
32#define COREPOR_RST BIT(5)
33#define CORE_RST BIT(4)
34#define L2DT_SLP BIT(3)
35#define CLAMP BIT(0)
36
37#define APC_PWR_GATE_CTL 0x14
38#define BHS_CNT_SHIFT 24
39#define LDO_PWR_DWN_SHIFT 16
40#define LDO_BYP_SHIFT 8
41#define BHS_SEG_SHIFT 1
42#define BHS_EN BIT(0)
43
44#define APCS_SAW2_VCTL 0x14
45#define APCS_SAW2_2_VCTL 0x1c
46
47extern void secondary_startup(void);
48
49static DEFINE_SPINLOCK(boot_lock);
50
51#ifdef CONFIG_HOTPLUG_CPU
52static void __ref qcom_cpu_die(unsigned int cpu)
53{
54 wfi();
55}
56#endif
57
58static void qcom_secondary_init(unsigned int cpu)
59{
60 /*
61 * Synchronise with the boot thread.
62 */
63 spin_lock(&boot_lock);
64 spin_unlock(&boot_lock);
65}
66
67static int scss_release_secondary(unsigned int cpu)
68{
69 struct device_node *node;
70 void __iomem *base;
71
72 node = of_find_compatible_node(NULL, NULL, "qcom,gcc-msm8660");
73 if (!node) {
74 pr_err("%s: can't find node\n", __func__);
75 return -ENXIO;
76 }
77
78 base = of_iomap(node, 0);
79 of_node_put(node);
80 if (!base)
81 return -ENOMEM;
82
83 writel_relaxed(0, base + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
84 writel_relaxed(0, base + SCSS_CPU1CORE_RESET);
85 writel_relaxed(3, base + SCSS_DBG_STATUS_CORE_PWRDUP);
86 mb();
87 iounmap(base);
88
89 return 0;
90}
91
92static int kpssv1_release_secondary(unsigned int cpu)
93{
94 int ret = 0;
95 void __iomem *reg, *saw_reg;
96 struct device_node *cpu_node, *acc_node, *saw_node;
97 u32 val;
98
99 cpu_node = of_get_cpu_node(cpu, NULL);
100 if (!cpu_node)
101 return -ENODEV;
102
103 acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
104 if (!acc_node) {
105 ret = -ENODEV;
106 goto out_acc;
107 }
108
109 saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
110 if (!saw_node) {
111 ret = -ENODEV;
112 goto out_saw;
113 }
114
115 reg = of_iomap(acc_node, 0);
116 if (!reg) {
117 ret = -ENOMEM;
118 goto out_acc_map;
119 }
120
121 saw_reg = of_iomap(saw_node, 0);
122 if (!saw_reg) {
123 ret = -ENOMEM;
124 goto out_saw_map;
125 }
126
127 /* Turn on CPU rail */
128 writel_relaxed(0xA4, saw_reg + APCS_SAW2_VCTL);
129 mb();
130 udelay(512);
131
132 /* Krait bring-up sequence */
133 val = PLL_CLAMP | L2DT_SLP | CLAMP;
134 writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
135 val &= ~L2DT_SLP;
136 writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
137 mb();
138 ndelay(300);
139
140 val |= COREPOR_RST;
141 writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
142 mb();
143 udelay(2);
144
145 val &= ~CLAMP;
146 writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
147 mb();
148 udelay(2);
149
150 val &= ~COREPOR_RST;
151 writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
152 mb();
153 udelay(100);
154
155 val |= CORE_PWRD_UP;
156 writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
157 mb();
158
159 iounmap(saw_reg);
160out_saw_map:
161 iounmap(reg);
162out_acc_map:
163 of_node_put(saw_node);
164out_saw:
165 of_node_put(acc_node);
166out_acc:
167 of_node_put(cpu_node);
168 return ret;
169}
170
171static int kpssv2_release_secondary(unsigned int cpu)
172{
173 void __iomem *reg;
174 struct device_node *cpu_node, *l2_node, *acc_node, *saw_node;
175 void __iomem *l2_saw_base;
176 unsigned reg_val;
177 int ret;
178
179 cpu_node = of_get_cpu_node(cpu, NULL);
180 if (!cpu_node)
181 return -ENODEV;
182
183 acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
184 if (!acc_node) {
185 ret = -ENODEV;
186 goto out_acc;
187 }
188
189 l2_node = of_parse_phandle(cpu_node, "next-level-cache", 0);
190 if (!l2_node) {
191 ret = -ENODEV;
192 goto out_l2;
193 }
194
195 saw_node = of_parse_phandle(l2_node, "qcom,saw", 0);
196 if (!saw_node) {
197 ret = -ENODEV;
198 goto out_saw;
199 }
200
201 reg = of_iomap(acc_node, 0);
202 if (!reg) {
203 ret = -ENOMEM;
204 goto out_map;
205 }
206
207 l2_saw_base = of_iomap(saw_node, 0);
208 if (!l2_saw_base) {
209 ret = -ENOMEM;
210 goto out_saw_map;
211 }
212
213 /* Turn on the BHS, turn off LDO Bypass and power down LDO */
214 reg_val = (64 << BHS_CNT_SHIFT) | (0x3f << LDO_PWR_DWN_SHIFT) | BHS_EN;
215 writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
216 mb();
217 /* wait for the BHS to settle */
218 udelay(1);
219
220 /* Turn on BHS segments */
221 reg_val |= 0x3f << BHS_SEG_SHIFT;
222 writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
223 mb();
224 /* wait for the BHS to settle */
225 udelay(1);
226
227 /* Finally turn on the bypass so that BHS supplies power */
228 reg_val |= 0x3f << LDO_BYP_SHIFT;
229 writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
230
231 /* enable max phases */
232 writel_relaxed(0x10003, l2_saw_base + APCS_SAW2_2_VCTL);
233 mb();
234 udelay(50);
235
236 reg_val = COREPOR_RST | CLAMP;
237 writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
238 mb();
239 udelay(2);
240
241 reg_val &= ~CLAMP;
242 writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
243 mb();
244 udelay(2);
245
246 reg_val &= ~COREPOR_RST;
247 writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
248 mb();
249
250 reg_val |= CORE_PWRD_UP;
251 writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
252 mb();
253
254 ret = 0;
255
256 iounmap(l2_saw_base);
257out_saw_map:
258 iounmap(reg);
259out_map:
260 of_node_put(saw_node);
261out_saw:
262 of_node_put(l2_node);
263out_l2:
264 of_node_put(acc_node);
265out_acc:
266 of_node_put(cpu_node);
267
268 return ret;
269}
270
271static DEFINE_PER_CPU(int, cold_boot_done);
272
273static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
274{
275 int ret = 0;
276
277 if (!per_cpu(cold_boot_done, cpu)) {
278 ret = func(cpu);
279 if (!ret)
280 per_cpu(cold_boot_done, cpu) = true;
281 }
282
283 /*
284 * set synchronisation state between this boot processor
285 * and the secondary one
286 */
287 spin_lock(&boot_lock);
288
289 /*
290 * Send the secondary CPU a soft interrupt, thereby causing
291 * the boot monitor to read the system wide flags register,
292 * and branch to the address found there.
293 */
294 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
295
296 /*
297 * now the secondary core is starting up let it run its
298 * calibrations, then wait for it to finish
299 */
300 spin_unlock(&boot_lock);
301
302 return ret;
303}
304
305static int msm8660_boot_secondary(unsigned int cpu, struct task_struct *idle)
306{
307 return qcom_boot_secondary(cpu, scss_release_secondary);
308}
309
310static int kpssv1_boot_secondary(unsigned int cpu, struct task_struct *idle)
311{
312 return qcom_boot_secondary(cpu, kpssv1_release_secondary);
313}
314
315static int kpssv2_boot_secondary(unsigned int cpu, struct task_struct *idle)
316{
317 return qcom_boot_secondary(cpu, kpssv2_release_secondary);
318}
319
320static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
321{
322 int cpu, map;
323 unsigned int flags = 0;
324 static const int cold_boot_flags[] = {
325 0,
326 SCM_FLAG_COLDBOOT_CPU1,
327 SCM_FLAG_COLDBOOT_CPU2,
328 SCM_FLAG_COLDBOOT_CPU3,
329 };
330
331 for_each_present_cpu(cpu) {
332 map = cpu_logical_map(cpu);
333 if (WARN_ON(map >= ARRAY_SIZE(cold_boot_flags))) {
334 set_cpu_present(cpu, false);
335 continue;
336 }
337 flags |= cold_boot_flags[map];
338 }
339
340 if (scm_set_boot_addr(virt_to_phys(secondary_startup), flags)) {
341 for_each_present_cpu(cpu) {
342 if (cpu == smp_processor_id())
343 continue;
344 set_cpu_present(cpu, false);
345 }
346 pr_warn("Failed to set CPU boot address, disabling SMP\n");
347 }
348}
349
350static struct smp_operations smp_msm8660_ops __initdata = {
351 .smp_prepare_cpus = qcom_smp_prepare_cpus,
352 .smp_secondary_init = qcom_secondary_init,
353 .smp_boot_secondary = msm8660_boot_secondary,
354#ifdef CONFIG_HOTPLUG_CPU
355 .cpu_die = qcom_cpu_die,
356#endif
357};
358CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
359
360static struct smp_operations qcom_smp_kpssv1_ops __initdata = {
361 .smp_prepare_cpus = qcom_smp_prepare_cpus,
362 .smp_secondary_init = qcom_secondary_init,
363 .smp_boot_secondary = kpssv1_boot_secondary,
364#ifdef CONFIG_HOTPLUG_CPU
365 .cpu_die = qcom_cpu_die,
366#endif
367};
368CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
369
370static struct smp_operations qcom_smp_kpssv2_ops __initdata = {
371 .smp_prepare_cpus = qcom_smp_prepare_cpus,
372 .smp_secondary_init = qcom_secondary_init,
373 .smp_boot_secondary = kpssv2_boot_secondary,
374#ifdef CONFIG_HOTPLUG_CPU
375 .cpu_die = qcom_cpu_die,
376#endif
377};
378CPU_METHOD_OF_DECLARE(qcom_smp_kpssv2, "qcom,kpss-acc-v2", &qcom_smp_kpssv2_ops);
diff --git a/arch/arm/mach-msm/scm-boot.c b/arch/arm/mach-qcom/scm-boot.c
index 45cee3e469a5..45cee3e469a5 100644
--- a/arch/arm/mach-msm/scm-boot.c
+++ b/arch/arm/mach-qcom/scm-boot.c
diff --git a/arch/arm/mach-msm/scm-boot.h b/arch/arm/mach-qcom/scm-boot.h
index 7be32ff5d687..6aabb2428176 100644
--- a/arch/arm/mach-msm/scm-boot.h
+++ b/arch/arm/mach-qcom/scm-boot.h
@@ -13,9 +13,11 @@
13#define __MACH_SCM_BOOT_H 13#define __MACH_SCM_BOOT_H
14 14
15#define SCM_BOOT_ADDR 0x1 15#define SCM_BOOT_ADDR 0x1
16#define SCM_FLAG_COLDBOOT_CPU1 0x1 16#define SCM_FLAG_COLDBOOT_CPU1 0x01
17#define SCM_FLAG_WARMBOOT_CPU1 0x2 17#define SCM_FLAG_COLDBOOT_CPU2 0x08
18#define SCM_FLAG_WARMBOOT_CPU0 0x4 18#define SCM_FLAG_COLDBOOT_CPU3 0x20
19#define SCM_FLAG_WARMBOOT_CPU0 0x04
20#define SCM_FLAG_WARMBOOT_CPU1 0x02
19 21
20int scm_set_boot_addr(phys_addr_t addr, int flags); 22int scm_set_boot_addr(phys_addr_t addr, int flags);
21 23
diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-qcom/scm.c
index c536fd6bf827..c536fd6bf827 100644
--- a/arch/arm/mach-msm/scm.c
+++ b/arch/arm/mach-qcom/scm.c
diff --git a/arch/arm/mach-msm/scm.h b/arch/arm/mach-qcom/scm.h
index 00b31ea58f29..00b31ea58f29 100644
--- a/arch/arm/mach-msm/scm.h
+++ b/arch/arm/mach-qcom/scm.h