aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGregory CLEMENT <gregory.clement@free-electrons.com>2012-08-02 04:16:29 -0400
committerGregory CLEMENT <gregory.clement@free-electrons.com>2012-11-21 10:49:06 -0500
commit009f13159bfdccd6e06fe3b62a39fee6dce26c39 (patch)
tree681d68bde140a819f18af537a51131c850dc8edb /arch
parent1611f872513735ac7105535689c0dd668fbf1c04 (diff)
arm: mvebu: Add support for coherency fabric in mach-mvebu
The Armada 370 and Armada XP SOCs have a coherency fabric unit which is responsible for ensuring hardware coherency between all CPUs and between CPUs and I/O masters. This patch provides the basic support needed for SMP. Signed-off-by: Yehuda Yitschak <yehuday@marvell.com> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Reviewed-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/boot/dts/armada-370-xp.dtsi5
-rw-r--r--arch/arm/mach-mvebu/Makefile2
-rw-r--r--arch/arm/mach-mvebu/coherency.c82
-rw-r--r--arch/arm/mach-mvebu/coherency.h24
-rw-r--r--arch/arm/mach-mvebu/coherency_ll.S49
-rw-r--r--arch/arm/mach-mvebu/common.h1
6 files changed, 162 insertions, 1 deletions
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 94b4b9e03571..b0d075b50f29 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -36,6 +36,11 @@
36 interrupt-controller; 36 interrupt-controller;
37 }; 37 };
38 38
39 coherency-fabric@d0020200 {
40 compatible = "marvell,coherency-fabric";
41 reg = <0xd0020200 0xb0>;
42 };
43
39 soc { 44 soc {
40 #address-cells = <1>; 45 #address-cells = <1>;
41 #size-cells = <1>; 46 #size-cells = <1>;
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index 57f996b6aa0e..5ce4b42c2697 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -2,4 +2,4 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
2 -I$(srctree)/arch/arm/plat-orion/include 2 -I$(srctree)/arch/arm/plat-orion/include
3 3
4obj-y += system-controller.o 4obj-y += system-controller.o
5obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o 5obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o coherency.o coherency_ll.o
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
new file mode 100644
index 000000000000..596ee66a9cc4
--- /dev/null
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -0,0 +1,82 @@
1/*
2 * Coherency fabric (Aurora) support for Armada 370 and XP platforms.
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Yehuda Yitschak <yehuday@marvell.com>
7 * Gregory Clement <gregory.clement@free-electrons.com>
8 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
9 *
10 * This file is licensed under the terms of the GNU General Public
11 * License version 2. This program is licensed "as is" without any
12 * warranty of any kind, whether express or implied.
13 *
14 * The Armada 370 and Armada XP SOCs have a coherency fabric which is
15 * responsible for ensuring hardware coherency between all CPUs and between
16 * CPUs and I/O masters. This file initializes the coherency fabric and
17 * supplies basic routines for configuring and controlling hardware coherency
18 */
19
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/of_address.h>
23#include <linux/io.h>
24#include <linux/smp.h>
25#include <asm/smp_plat.h>
26#include "armada-370-xp.h"
27
28/*
29 * Some functions in this file are called very early during SMP
30 * initialization. At that time the device tree framework is not yet
31 * ready, and it is not possible to get the register address to
32 * ioremap it. That's why the pointer below is given with an initial
33 * value matching its virtual mapping
34 */
35static void __iomem *coherency_base = ARMADA_370_XP_REGS_VIRT_BASE + 0x20200;
36
37/* Coherency fabric registers */
38#define COHERENCY_FABRIC_CFG_OFFSET 0x4
39
40static struct of_device_id of_coherency_table[] = {
41 {.compatible = "marvell,coherency-fabric"},
42 { /* end of list */ },
43};
44
45#ifdef CONFIG_SMP
46int coherency_get_cpu_count(void)
47{
48 int reg, cnt;
49
50 reg = readl(coherency_base + COHERENCY_FABRIC_CFG_OFFSET);
51 cnt = (reg & 0xF) + 1;
52
53 return cnt;
54}
55#endif
56
57/* Function defined in coherency_ll.S */
58int ll_set_cpu_coherent(void __iomem *base_addr, unsigned int hw_cpu_id);
59
60int set_cpu_coherent(unsigned int hw_cpu_id, int smp_group_id)
61{
62 if (!coherency_base) {
63 pr_warn("Can't make CPU %d cache coherent.\n", hw_cpu_id);
64 pr_warn("Coherency fabric is not initialized\n");
65 return 1;
66 }
67
68 return ll_set_cpu_coherent(coherency_base, hw_cpu_id);
69}
70
71int __init coherency_init(void)
72{
73 struct device_node *np;
74
75 np = of_find_matching_node(NULL, of_coherency_table);
76 if (np) {
77 pr_info("Initializing Coherency fabric\n");
78 coherency_base = of_iomap(np, 0);
79 }
80
81 return 0;
82}
diff --git a/arch/arm/mach-mvebu/coherency.h b/arch/arm/mach-mvebu/coherency.h
new file mode 100644
index 000000000000..2f428137f6fe
--- /dev/null
+++ b/arch/arm/mach-mvebu/coherency.h
@@ -0,0 +1,24 @@
1/*
2 * arch/arm/mach-mvebu/include/mach/coherency.h
3 *
4 *
5 * Coherency fabric (Aurora) support for Armada 370 and XP platforms.
6 *
7 * Copyright (C) 2012 Marvell
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#ifndef __MACH_370_XP_COHERENCY_H
15#define __MACH_370_XP_COHERENCY_H
16
17#ifdef CONFIG_SMP
18int coherency_get_cpu_count(void);
19#endif
20
21int set_cpu_coherent(int cpu_id, int smp_group_id);
22int coherency_init(void);
23
24#endif /* __MACH_370_XP_COHERENCY_H */
diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S
new file mode 100644
index 000000000000..53e8391192cd
--- /dev/null
+++ b/arch/arm/mach-mvebu/coherency_ll.S
@@ -0,0 +1,49 @@
1/*
2 * Coherency fabric: low level functions
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Gregory CLEMENT <gregory.clement@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 *
12 * This file implements the assembly function to add a CPU to the
13 * coherency fabric. This function is called by each of the secondary
14 * CPUs during their early boot in an SMP kernel, this why this
15 * function have to callable from assembly. It can also be called by a
16 * primary CPU from C code during its boot.
17 */
18
19#include <linux/linkage.h>
20#define ARMADA_XP_CFB_CTL_REG_OFFSET 0x0
21#define ARMADA_XP_CFB_CFG_REG_OFFSET 0x4
22
23 .text
24/*
25 * r0: Coherency fabric base register address
26 * r1: HW CPU id
27 */
28ENTRY(ll_set_cpu_coherent)
29 /* Create bit by cpu index */
30 mov r3, #(1 << 24)
31 lsl r1, r3, r1
32
33 /* Add CPU to SMP group - Atomic */
34 add r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET
35 ldr r2, [r3]
36 orr r2, r2, r1
37 str r2, [r3]
38
39 /* Enable coherency on CPU - Atomic */
40 add r3, r0, #ARMADA_XP_CFB_CFG_REG_OFFSET
41 ldr r2, [r3]
42 orr r2, r2, r1
43 str r2, [r3]
44
45 dsb
46
47 mov r0, #0
48 mov pc, lr
49ENDPROC(ll_set_cpu_coherent)
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
index 02f89eaa25fe..ba6b62a42f52 100644
--- a/arch/arm/mach-mvebu/common.h
+++ b/arch/arm/mach-mvebu/common.h
@@ -20,4 +20,5 @@ void mvebu_restart(char mode, const char *cmd);
20void armada_370_xp_init_irq(void); 20void armada_370_xp_init_irq(void);
21void armada_370_xp_handle_irq(struct pt_regs *regs); 21void armada_370_xp_handle_irq(struct pt_regs *regs);
22 22
23int armada_370_xp_coherency_init(void);
23#endif 24#endif