aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mvebu
diff options
context:
space:
mode:
authorJason Cooper <jason@lakedaemon.net>2014-07-24 07:41:36 -0400
committerJason Cooper <jason@lakedaemon.net>2014-07-24 07:41:36 -0400
commit5abe65e3d67aac9f9b5c08660f817a2d6ec5515f (patch)
tree7422d99151ab4967a4b0f1783a156e6a1527ccde /arch/arm/mach-mvebu
parentba364fc752daeded072a5ef31e43b84cb1f9e5fd (diff)
parenta728b977429383b3fe92b6e3bff9e69365609e0f (diff)
Merge branch 'mvebu/fixes' into mvebu/soc-cpuidle
Diffstat (limited to 'arch/arm/mach-mvebu')
-rw-r--r--arch/arm/mach-mvebu/Kconfig2
-rw-r--r--arch/arm/mach-mvebu/Makefile2
-rw-r--r--arch/arm/mach-mvebu/board-v7.c29
-rw-r--r--arch/arm/mach-mvebu/coherency.c6
-rw-r--r--arch/arm/mach-mvebu/headsmp-a9.S9
-rw-r--r--arch/arm/mach-mvebu/pmsu.c19
-rw-r--r--arch/arm/mach-mvebu/pmsu_ll.S25
7 files changed, 67 insertions, 25 deletions
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index e5ab3a7cb3d2..8e3b5f12cd7c 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -10,6 +10,7 @@ config ARCH_MVEBU
10 select ZONE_DMA if ARM_LPAE 10 select ZONE_DMA if ARM_LPAE
11 select ARCH_REQUIRE_GPIOLIB 11 select ARCH_REQUIRE_GPIOLIB
12 select PCI_QUIRKS if PCI 12 select PCI_QUIRKS if PCI
13 select OF_ADDRESS_PCI
13 14
14if ARCH_MVEBU 15if ARCH_MVEBU
15 16
@@ -19,6 +20,7 @@ config MACH_MVEBU_V7
19 bool 20 bool
20 select ARMADA_370_XP_TIMER 21 select ARMADA_370_XP_TIMER
21 select CACHE_L2X0 22 select CACHE_L2X0
23 select ARM_CPU_SUSPEND
22 24
23config MACH_ARMADA_370 25config MACH_ARMADA_370
24 bool "Marvell Armada 370 boards" if ARCH_MULTI_V7 26 bool "Marvell Armada 370 boards" if ARCH_MULTI_V7
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index 90bcd5327312..bc7689e530a4 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -7,7 +7,7 @@ CFLAGS_pmsu.o := -march=armv7-a
7obj-y += system-controller.o mvebu-soc-id.o 7obj-y += system-controller.o mvebu-soc-id.o
8 8
9ifeq ($(CONFIG_MACH_MVEBU_V7),y) 9ifeq ($(CONFIG_MACH_MVEBU_V7),y)
10obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o 10obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o pmsu_ll.o
11obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o 11obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o
12endif 12endif
13 13
diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c
index a04675e2ec99..f244622ffc00 100644
--- a/arch/arm/mach-mvebu/board-v7.c
+++ b/arch/arm/mach-mvebu/board-v7.c
@@ -23,6 +23,7 @@
23#include <linux/mbus.h> 23#include <linux/mbus.h>
24#include <linux/signal.h> 24#include <linux/signal.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/irqchip.h>
26#include <asm/hardware/cache-l2x0.h> 27#include <asm/hardware/cache-l2x0.h>
27#include <asm/mach/arch.h> 28#include <asm/mach/arch.h>
28#include <asm/mach/map.h> 29#include <asm/mach/map.h>
@@ -71,17 +72,23 @@ static int armada_375_external_abort_wa(unsigned long addr, unsigned int fsr,
71 return 1; 72 return 1;
72} 73}
73 74
74static void __init mvebu_timer_and_clk_init(void) 75static void __init mvebu_init_irq(void)
75{ 76{
76 of_clk_init(NULL); 77 irqchip_init();
77 clocksource_of_init();
78 mvebu_scu_enable(); 78 mvebu_scu_enable();
79 coherency_init(); 79 coherency_init();
80 BUG_ON(mvebu_mbus_dt_init(coherency_available())); 80 BUG_ON(mvebu_mbus_dt_init(coherency_available()));
81}
82
83static void __init external_abort_quirk(void)
84{
85 u32 dev, rev;
81 86
82 if (of_machine_is_compatible("marvell,armada375")) 87 if (mvebu_get_soc_id(&dev, &rev) == 0 && rev > ARMADA_375_Z1_REV)
83 hook_fault_code(16 + 6, armada_375_external_abort_wa, SIGBUS, 0, 88 return;
84 "imprecise external abort"); 89
90 hook_fault_code(16 + 6, armada_375_external_abort_wa, SIGBUS, 0,
91 "imprecise external abort");
85} 92}
86 93
87static void __init i2c_quirk(void) 94static void __init i2c_quirk(void)
@@ -178,8 +185,10 @@ static void __init mvebu_dt_init(void)
178{ 185{
179 if (of_machine_is_compatible("plathome,openblocks-ax3-4")) 186 if (of_machine_is_compatible("plathome,openblocks-ax3-4"))
180 i2c_quirk(); 187 i2c_quirk();
181 if (of_machine_is_compatible("marvell,a375-db")) 188 if (of_machine_is_compatible("marvell,a375-db")) {
189 external_abort_quirk();
182 thermal_quirk(); 190 thermal_quirk();
191 }
183 192
184 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 193 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
185} 194}
@@ -194,7 +203,7 @@ DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)")
194 .l2c_aux_mask = ~0, 203 .l2c_aux_mask = ~0,
195 .smp = smp_ops(armada_xp_smp_ops), 204 .smp = smp_ops(armada_xp_smp_ops),
196 .init_machine = mvebu_dt_init, 205 .init_machine = mvebu_dt_init,
197 .init_time = mvebu_timer_and_clk_init, 206 .init_irq = mvebu_init_irq,
198 .restart = mvebu_restart, 207 .restart = mvebu_restart,
199 .dt_compat = armada_370_xp_dt_compat, 208 .dt_compat = armada_370_xp_dt_compat,
200MACHINE_END 209MACHINE_END
@@ -207,7 +216,7 @@ static const char * const armada_375_dt_compat[] = {
207DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)") 216DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)")
208 .l2c_aux_val = 0, 217 .l2c_aux_val = 0,
209 .l2c_aux_mask = ~0, 218 .l2c_aux_mask = ~0,
210 .init_time = mvebu_timer_and_clk_init, 219 .init_irq = mvebu_init_irq,
211 .init_machine = mvebu_dt_init, 220 .init_machine = mvebu_dt_init,
212 .restart = mvebu_restart, 221 .restart = mvebu_restart,
213 .dt_compat = armada_375_dt_compat, 222 .dt_compat = armada_375_dt_compat,
@@ -222,7 +231,7 @@ static const char * const armada_38x_dt_compat[] = {
222DT_MACHINE_START(ARMADA_38X_DT, "Marvell Armada 380/385 (Device Tree)") 231DT_MACHINE_START(ARMADA_38X_DT, "Marvell Armada 380/385 (Device Tree)")
223 .l2c_aux_val = 0, 232 .l2c_aux_val = 0,
224 .l2c_aux_mask = ~0, 233 .l2c_aux_mask = ~0,
225 .init_time = mvebu_timer_and_clk_init, 234 .init_irq = mvebu_init_irq,
226 .restart = mvebu_restart, 235 .restart = mvebu_restart,
227 .dt_compat = armada_38x_dt_compat, 236 .dt_compat = armada_38x_dt_compat,
228MACHINE_END 237MACHINE_END
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
index 477202fd39cc..2bdc3233abe2 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -292,6 +292,10 @@ static struct notifier_block mvebu_hwcc_nb = {
292 .notifier_call = mvebu_hwcc_notifier, 292 .notifier_call = mvebu_hwcc_notifier,
293}; 293};
294 294
295static struct notifier_block mvebu_hwcc_pci_nb = {
296 .notifier_call = mvebu_hwcc_notifier,
297};
298
295static void __init armada_370_coherency_init(struct device_node *np) 299static void __init armada_370_coherency_init(struct device_node *np)
296{ 300{
297 struct resource res; 301 struct resource res;
@@ -427,7 +431,7 @@ static int __init coherency_pci_init(void)
427{ 431{
428 if (coherency_available()) 432 if (coherency_available())
429 bus_register_notifier(&pci_bus_type, 433 bus_register_notifier(&pci_bus_type,
430 &mvebu_hwcc_nb); 434 &mvebu_hwcc_pci_nb);
431 return 0; 435 return 0;
432} 436}
433 437
diff --git a/arch/arm/mach-mvebu/headsmp-a9.S b/arch/arm/mach-mvebu/headsmp-a9.S
index 5925366bc03c..da5bb292b91c 100644
--- a/arch/arm/mach-mvebu/headsmp-a9.S
+++ b/arch/arm/mach-mvebu/headsmp-a9.S
@@ -15,6 +15,8 @@
15#include <linux/linkage.h> 15#include <linux/linkage.h>
16#include <linux/init.h> 16#include <linux/init.h>
17 17
18#include <asm/assembler.h>
19
18 __CPUINIT 20 __CPUINIT
19#define CPU_RESUME_ADDR_REG 0xf10182d4 21#define CPU_RESUME_ADDR_REG 0xf10182d4
20 22
@@ -22,13 +24,18 @@
22.global armada_375_smp_cpu1_enable_code_end 24.global armada_375_smp_cpu1_enable_code_end
23 25
24armada_375_smp_cpu1_enable_code_start: 26armada_375_smp_cpu1_enable_code_start:
25 ldr r0, [pc, #4] 27ARM_BE8(setend be)
28 adr r0, 1f
29 ldr r0, [r0]
26 ldr r1, [r0] 30 ldr r1, [r0]
31ARM_BE8(rev r1, r1)
27 mov pc, r1 32 mov pc, r1
331:
28 .word CPU_RESUME_ADDR_REG 34 .word CPU_RESUME_ADDR_REG
29armada_375_smp_cpu1_enable_code_end: 35armada_375_smp_cpu1_enable_code_end:
30 36
31ENTRY(mvebu_cortex_a9_secondary_startup) 37ENTRY(mvebu_cortex_a9_secondary_startup)
38ARM_BE8(setend be)
32 bl v7_invalidate_l1 39 bl v7_invalidate_l1
33 b secondary_startup 40 b secondary_startup
34ENDPROC(mvebu_cortex_a9_secondary_startup) 41ENDPROC(mvebu_cortex_a9_secondary_startup)
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 9c819d65b337..b31a8293a347 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -66,6 +66,8 @@ static void __iomem *pmsu_mp_base;
66extern void ll_disable_coherency(void); 66extern void ll_disable_coherency(void);
67extern void ll_enable_coherency(void); 67extern void ll_enable_coherency(void);
68 68
69extern void armada_370_xp_cpu_resume(void);
70
69static struct platform_device armada_xp_cpuidle_device = { 71static struct platform_device armada_xp_cpuidle_device = {
70 .name = "cpuidle-armada-370-xp", 72 .name = "cpuidle-armada-370-xp",
71}; 73};
@@ -140,13 +142,6 @@ static void armada_370_xp_pmsu_enable_l2_powerdown_onidle(void)
140 writel(reg, pmsu_mp_base + L2C_NFABRIC_PM_CTL); 142 writel(reg, pmsu_mp_base + L2C_NFABRIC_PM_CTL);
141} 143}
142 144
143static void armada_370_xp_cpu_resume(void)
144{
145 asm volatile("bl ll_add_cpu_to_smp_group\n\t"
146 "bl ll_enable_coherency\n\t"
147 "b cpu_resume\n\t");
148}
149
150/* No locking is needed because we only access per-CPU registers */ 145/* No locking is needed because we only access per-CPU registers */
151int armada_370_xp_pmsu_idle_enter(unsigned long deepidle) 146int armada_370_xp_pmsu_idle_enter(unsigned long deepidle)
152{ 147{
@@ -201,12 +196,12 @@ int armada_370_xp_pmsu_idle_enter(unsigned long deepidle)
201 196
202 /* Test the CR_C bit and set it if it was cleared */ 197 /* Test the CR_C bit and set it if it was cleared */
203 asm volatile( 198 asm volatile(
204 "mrc p15, 0, %0, c1, c0, 0 \n\t" 199 "mrc p15, 0, r0, c1, c0, 0 \n\t"
205 "tst %0, #(1 << 2) \n\t" 200 "tst r0, #(1 << 2) \n\t"
206 "orreq %0, %0, #(1 << 2) \n\t" 201 "orreq r0, r0, #(1 << 2) \n\t"
207 "mcreq p15, 0, %0, c1, c0, 0 \n\t" 202 "mcreq p15, 0, r0, c1, c0, 0 \n\t"
208 "isb " 203 "isb "
209 : : "r" (0)); 204 : : : "r0");
210 205
211 pr_warn("Failed to suspend the system\n"); 206 pr_warn("Failed to suspend the system\n");
212 207
diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
new file mode 100644
index 000000000000..fc3de68d8c54
--- /dev/null
+++ b/arch/arm/mach-mvebu/pmsu_ll.S
@@ -0,0 +1,25 @@
1/*
2 * Copyright (C) 2014 Marvell
3 *
4 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
5 * Gregory Clement <gregory.clement@free-electrons.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/linkage.h>
13#include <asm/assembler.h>
14
15/*
16 * This is the entry point through which CPUs exiting cpuidle deep
17 * idle state are going.
18 */
19ENTRY(armada_370_xp_cpu_resume)
20ARM_BE8(setend be ) @ go BE8 if entered LE
21 bl ll_add_cpu_to_smp_group
22 bl ll_enable_coherency
23 b cpu_resume
24ENDPROC(armada_370_xp_cpu_resume)
25