aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mvebu/coherency.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-mvebu/coherency.c')
-rw-r--r--arch/arm/mach-mvebu/coherency.c82
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 */
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}