aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>2014-11-13 04:38:59 -0500
committerJason Cooper <jason@lakedaemon.net>2014-11-21 20:49:37 -0500
commitef01c6c36bb8d176e5f2302507fb1f688875d3ab (patch)
tree39ad84a954d2d1856ecd3d5f2d01db0962d2d2b0
parent3b8509b5f2c14403d4bfaec56842ad0ed5389022 (diff)
ARM: mvebu: remove Armada 375 Z1 workaround for I/O coherency
This reverts commit 5ab5afd8ba83 ("ARM: mvebu: implement Armada 375 coherency workaround"), since we are removing the support for the very early Z1 revision of the Armada 375 SoC. This commit is an exact revert, with two exceptions: - minor adaptations needed due to other changes that have taken place in coherency.c since the original commit - keep the definition of pr_fmt. This shouldn't originally have been part of the Armada 375 Z1 workaround commit since it had nothing to do with it. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Link: https://lkml.kernel.org/r/1415871540-20302-5-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r--arch/arm/mach-mvebu/coherency.c169
1 files changed, 3 insertions, 166 deletions
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
index db2f5bd280dd..e568b2ef6830 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -28,7 +28,6 @@
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/mbus.h> 30#include <linux/mbus.h>
31#include <linux/clk.h>
32#include <linux/pci.h> 31#include <linux/pci.h>
33#include <asm/smp_plat.h> 32#include <asm/smp_plat.h>
34#include <asm/cacheflush.h> 33#include <asm/cacheflush.h>
@@ -77,157 +76,8 @@ int set_cpu_coherent(void)
77 return ll_enable_coherency(); 76 return ll_enable_coherency();
78} 77}
79 78
80/*
81 * The below code implements the I/O coherency workaround on Armada
82 * 375. This workaround consists in using the two channels of the
83 * first XOR engine to trigger a XOR transaction that serves as the
84 * I/O coherency barrier.
85 */
86
87static void __iomem *xor_base, *xor_high_base;
88static dma_addr_t coherency_wa_buf_phys[CONFIG_NR_CPUS];
89static void *coherency_wa_buf[CONFIG_NR_CPUS];
90static bool coherency_wa_enabled;
91
92#define XOR_CONFIG(chan) (0x10 + (chan * 4))
93#define XOR_ACTIVATION(chan) (0x20 + (chan * 4))
94#define WINDOW_BAR_ENABLE(chan) (0x240 + ((chan) << 2))
95#define WINDOW_BASE(w) (0x250 + ((w) << 2))
96#define WINDOW_SIZE(w) (0x270 + ((w) << 2))
97#define WINDOW_REMAP_HIGH(w) (0x290 + ((w) << 2))
98#define WINDOW_OVERRIDE_CTRL(chan) (0x2A0 + ((chan) << 2))
99#define XOR_DEST_POINTER(chan) (0x2B0 + (chan * 4))
100#define XOR_BLOCK_SIZE(chan) (0x2C0 + (chan * 4))
101#define XOR_INIT_VALUE_LOW 0x2E0
102#define XOR_INIT_VALUE_HIGH 0x2E4
103
104static inline void mvebu_hwcc_armada375_sync_io_barrier_wa(void)
105{
106 int idx = smp_processor_id();
107
108 /* Write '1' to the first word of the buffer */
109 writel(0x1, coherency_wa_buf[idx]);
110
111 /* Wait until the engine is idle */
112 while ((readl(xor_base + XOR_ACTIVATION(idx)) >> 4) & 0x3)
113 ;
114
115 dmb();
116
117 /* Trigger channel */
118 writel(0x1, xor_base + XOR_ACTIVATION(idx));
119
120 /* Poll the data until it is cleared by the XOR transaction */
121 while (readl(coherency_wa_buf[idx]))
122 ;
123}
124
125static void __init armada_375_coherency_init_wa(void)
126{
127 const struct mbus_dram_target_info *dram;
128 struct device_node *xor_node;
129 struct property *xor_status;
130 struct clk *xor_clk;
131 u32 win_enable = 0;
132 int i;
133
134 pr_warn("enabling coherency workaround for Armada 375 Z1, one XOR engine disabled\n");
135
136 /*
137 * Since the workaround uses one XOR engine, we grab a
138 * reference to its Device Tree node first.
139 */
140 xor_node = of_find_compatible_node(NULL, NULL, "marvell,orion-xor");
141 BUG_ON(!xor_node);
142
143 /*
144 * Then we mark it as disabled so that the real XOR driver
145 * will not use it.
146 */
147 xor_status = kzalloc(sizeof(struct property), GFP_KERNEL);
148 BUG_ON(!xor_status);
149
150 xor_status->value = kstrdup("disabled", GFP_KERNEL);
151 BUG_ON(!xor_status->value);
152
153 xor_status->length = 8;
154 xor_status->name = kstrdup("status", GFP_KERNEL);
155 BUG_ON(!xor_status->name);
156
157 of_update_property(xor_node, xor_status);
158
159 /*
160 * And we remap the registers, get the clock, and do the
161 * initial configuration of the XOR engine.
162 */
163 xor_base = of_iomap(xor_node, 0);
164 xor_high_base = of_iomap(xor_node, 1);
165
166 xor_clk = of_clk_get_by_name(xor_node, NULL);
167 BUG_ON(!xor_clk);
168
169 clk_prepare_enable(xor_clk);
170
171 dram = mv_mbus_dram_info();
172
173 for (i = 0; i < 8; i++) {
174 writel(0, xor_base + WINDOW_BASE(i));
175 writel(0, xor_base + WINDOW_SIZE(i));
176 if (i < 4)
177 writel(0, xor_base + WINDOW_REMAP_HIGH(i));
178 }
179
180 for (i = 0; i < dram->num_cs; i++) {
181 const struct mbus_dram_window *cs = dram->cs + i;
182 writel((cs->base & 0xffff0000) |
183 (cs->mbus_attr << 8) |
184 dram->mbus_dram_target_id, xor_base + WINDOW_BASE(i));
185 writel((cs->size - 1) & 0xffff0000, xor_base + WINDOW_SIZE(i));
186
187 win_enable |= (1 << i);
188 win_enable |= 3 << (16 + (2 * i));
189 }
190
191 writel(win_enable, xor_base + WINDOW_BAR_ENABLE(0));
192 writel(win_enable, xor_base + WINDOW_BAR_ENABLE(1));
193 writel(0, xor_base + WINDOW_OVERRIDE_CTRL(0));
194 writel(0, xor_base + WINDOW_OVERRIDE_CTRL(1));
195
196 for (i = 0; i < CONFIG_NR_CPUS; i++) {
197 coherency_wa_buf[i] = kzalloc(PAGE_SIZE, GFP_KERNEL);
198 BUG_ON(!coherency_wa_buf[i]);
199
200 /*
201 * We can't use the DMA mapping API, since we don't
202 * have a valid 'struct device' pointer
203 */
204 coherency_wa_buf_phys[i] =
205 virt_to_phys(coherency_wa_buf[i]);
206 BUG_ON(!coherency_wa_buf_phys[i]);
207
208 /*
209 * Configure the XOR engine for memset operation, with
210 * a 128 bytes block size
211 */
212 writel(0x444, xor_base + XOR_CONFIG(i));
213 writel(128, xor_base + XOR_BLOCK_SIZE(i));
214 writel(coherency_wa_buf_phys[i],
215 xor_base + XOR_DEST_POINTER(i));
216 }
217
218 writel(0x0, xor_base + XOR_INIT_VALUE_LOW);
219 writel(0x0, xor_base + XOR_INIT_VALUE_HIGH);
220
221 coherency_wa_enabled = true;
222}
223
224static inline void mvebu_hwcc_sync_io_barrier(void) 79static inline void mvebu_hwcc_sync_io_barrier(void)
225{ 80{
226 if (coherency_wa_enabled) {
227 mvebu_hwcc_armada375_sync_io_barrier_wa();
228 return;
229 }
230
231 writel(0x1, coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET); 81 writel(0x1, coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET);
232 while (readl(coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET) & 0x1); 82 while (readl(coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET) & 0x1);
233} 83}
@@ -421,22 +271,9 @@ int __init coherency_init(void)
421 271
422static int __init coherency_late_init(void) 272static int __init coherency_late_init(void)
423{ 273{
424 int type = coherency_type(); 274 if (coherency_available())
425 275 bus_register_notifier(&platform_bus_type,
426 if (type == COHERENCY_FABRIC_TYPE_NONE) 276 &mvebu_hwcc_nb);
427 return 0;
428
429 if (type == COHERENCY_FABRIC_TYPE_ARMADA_375) {
430 u32 dev, rev;
431
432 if (mvebu_get_soc_id(&dev, &rev) == 0 &&
433 rev == ARMADA_375_Z1_REV)
434 armada_375_coherency_init_wa();
435 }
436
437 bus_register_notifier(&platform_bus_type,
438 &mvebu_hwcc_nb);
439
440 return 0; 277 return 0;
441} 278}
442 279