diff options
author | Arnd Bergmann <arnd@arndb.de> | 2015-10-15 16:03:35 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2015-10-15 16:03:35 -0400 |
commit | 19f47051e59d1366912705b367ceca26cdbe3428 (patch) | |
tree | 99711510fe73913b7b4e20ccb94c192aaeccb1e2 | |
parent | 55fa3ee0815a355490c109416935563223af0ccc (diff) | |
parent | d492cccac28493f26bb70038385a9ef4df19bdee (diff) |
Merge tag 'mvebu-soc-4.4-1' of git://git.infradead.org/linux-mvebu into next/soc
Merge "mvebu soc for 4.4 (part 1)" from Gregory CLEMENT:
L2 caches optimization for Armada XP
* tag 'mvebu-soc-4.4-1' of git://git.infradead.org/linux-mvebu:
ARM: mvebu: add support to clear shared L2 bit on Armada XP
-rw-r--r-- | Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt | 20 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/coherency.c | 60 |
2 files changed, 80 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt b/Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt new file mode 100644 index 000000000000..2cdcd716da40 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | MVEBU CPU Config registers | ||
2 | -------------------------- | ||
3 | |||
4 | MVEBU (Marvell SOCs: Armada 370/XP) | ||
5 | |||
6 | Required properties: | ||
7 | |||
8 | - compatible: one of: | ||
9 | - "marvell,armada-370-cpu-config" | ||
10 | - "marvell,armada-xp-cpu-config" | ||
11 | |||
12 | - reg: Should contain CPU config registers location and length, in | ||
13 | their per-CPU variant | ||
14 | |||
15 | Example: | ||
16 | |||
17 | cpu-config@21000 { | ||
18 | compatible = "marvell,armada-xp-cpu-config"; | ||
19 | reg = <0x21000 0x8>; | ||
20 | }; | ||
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index 44eedf331ae7..55348ee5a352 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c | |||
@@ -40,6 +40,7 @@ | |||
40 | unsigned long coherency_phys_base; | 40 | unsigned long coherency_phys_base; |
41 | void __iomem *coherency_base; | 41 | void __iomem *coherency_base; |
42 | static void __iomem *coherency_cpu_base; | 42 | static void __iomem *coherency_cpu_base; |
43 | static void __iomem *cpu_config_base; | ||
43 | 44 | ||
44 | /* Coherency fabric registers */ | 45 | /* Coherency fabric registers */ |
45 | #define IO_SYNC_BARRIER_CTL_OFFSET 0x0 | 46 | #define IO_SYNC_BARRIER_CTL_OFFSET 0x0 |
@@ -65,6 +66,31 @@ static const struct of_device_id of_coherency_table[] = { | |||
65 | int ll_enable_coherency(void); | 66 | int ll_enable_coherency(void); |
66 | void ll_add_cpu_to_smp_group(void); | 67 | void ll_add_cpu_to_smp_group(void); |
67 | 68 | ||
69 | #define CPU_CONFIG_SHARED_L2 BIT(16) | ||
70 | |||
71 | /* | ||
72 | * Disable the "Shared L2 Present" bit in CPU Configuration register | ||
73 | * on Armada XP. | ||
74 | * | ||
75 | * The "Shared L2 Present" bit affects the "level of coherence" value | ||
76 | * in the clidr CP15 register. Cache operation functions such as | ||
77 | * "flush all" and "invalidate all" operate on all the cache levels | ||
78 | * that included in the defined level of coherence. When HW I/O | ||
79 | * coherency is used, this bit causes unnecessary flushes of the L2 | ||
80 | * cache. | ||
81 | */ | ||
82 | static void armada_xp_clear_shared_l2(void) | ||
83 | { | ||
84 | u32 reg; | ||
85 | |||
86 | if (!cpu_config_base) | ||
87 | return; | ||
88 | |||
89 | reg = readl(cpu_config_base); | ||
90 | reg &= ~CPU_CONFIG_SHARED_L2; | ||
91 | writel(reg, cpu_config_base); | ||
92 | } | ||
93 | |||
68 | static int mvebu_hwcc_notifier(struct notifier_block *nb, | 94 | static int mvebu_hwcc_notifier(struct notifier_block *nb, |
69 | unsigned long event, void *__dev) | 95 | unsigned long event, void *__dev) |
70 | { | 96 | { |
@@ -85,9 +111,24 @@ static struct notifier_block mvebu_hwcc_pci_nb = { | |||
85 | .notifier_call = mvebu_hwcc_notifier, | 111 | .notifier_call = mvebu_hwcc_notifier, |
86 | }; | 112 | }; |
87 | 113 | ||
114 | static int armada_xp_clear_shared_l2_notifier_func(struct notifier_block *nfb, | ||
115 | unsigned long action, void *hcpu) | ||
116 | { | ||
117 | if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) | ||
118 | armada_xp_clear_shared_l2(); | ||
119 | |||
120 | return NOTIFY_OK; | ||
121 | } | ||
122 | |||
123 | static struct notifier_block armada_xp_clear_shared_l2_notifier = { | ||
124 | .notifier_call = armada_xp_clear_shared_l2_notifier_func, | ||
125 | .priority = 100, | ||
126 | }; | ||
127 | |||
88 | static void __init armada_370_coherency_init(struct device_node *np) | 128 | static void __init armada_370_coherency_init(struct device_node *np) |
89 | { | 129 | { |
90 | struct resource res; | 130 | struct resource res; |
131 | struct device_node *cpu_config_np; | ||
91 | 132 | ||
92 | of_address_to_resource(np, 0, &res); | 133 | of_address_to_resource(np, 0, &res); |
93 | coherency_phys_base = res.start; | 134 | coherency_phys_base = res.start; |
@@ -100,6 +141,23 @@ static void __init armada_370_coherency_init(struct device_node *np) | |||
100 | sync_cache_w(&coherency_phys_base); | 141 | sync_cache_w(&coherency_phys_base); |
101 | coherency_base = of_iomap(np, 0); | 142 | coherency_base = of_iomap(np, 0); |
102 | coherency_cpu_base = of_iomap(np, 1); | 143 | coherency_cpu_base = of_iomap(np, 1); |
144 | |||
145 | cpu_config_np = of_find_compatible_node(NULL, NULL, | ||
146 | "marvell,armada-xp-cpu-config"); | ||
147 | if (!cpu_config_np) | ||
148 | goto exit; | ||
149 | |||
150 | cpu_config_base = of_iomap(cpu_config_np, 0); | ||
151 | if (!cpu_config_base) { | ||
152 | of_node_put(cpu_config_np); | ||
153 | goto exit; | ||
154 | } | ||
155 | |||
156 | of_node_put(cpu_config_np); | ||
157 | |||
158 | register_cpu_notifier(&armada_xp_clear_shared_l2_notifier); | ||
159 | |||
160 | exit: | ||
103 | set_cpu_coherent(); | 161 | set_cpu_coherent(); |
104 | } | 162 | } |
105 | 163 | ||
@@ -204,6 +262,8 @@ int set_cpu_coherent(void) | |||
204 | pr_warn("Coherency fabric is not initialized\n"); | 262 | pr_warn("Coherency fabric is not initialized\n"); |
205 | return 1; | 263 | return 1; |
206 | } | 264 | } |
265 | |||
266 | armada_xp_clear_shared_l2(); | ||
207 | ll_add_cpu_to_smp_group(); | 267 | ll_add_cpu_to_smp_group(); |
208 | return ll_enable_coherency(); | 268 | return ll_enable_coherency(); |
209 | } | 269 | } |