diff options
Diffstat (limited to 'arch/arm/mach-mvebu/coherency.c')
-rw-r--r-- | arch/arm/mach-mvebu/coherency.c | 82 |
1 files changed, 82 insertions, 0 deletions
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 | */ | ||
35 | static void __iomem *coherency_base = ARMADA_370_XP_REGS_VIRT_BASE + 0x20200; | ||
36 | |||
37 | /* Coherency fabric registers */ | ||
38 | #define COHERENCY_FABRIC_CFG_OFFSET 0x4 | ||
39 | |||
40 | static struct of_device_id of_coherency_table[] = { | ||
41 | {.compatible = "marvell,coherency-fabric"}, | ||
42 | { /* end of list */ }, | ||
43 | }; | ||
44 | |||
45 | #ifdef CONFIG_SMP | ||
46 | int 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 */ | ||
58 | int ll_set_cpu_coherent(void __iomem *base_addr, unsigned int hw_cpu_id); | ||
59 | |||
60 | int 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 | |||
71 | int __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 | } | ||