summaryrefslogtreecommitdiffstats
path: root/sys/arm/arm
diff options
context:
space:
mode:
authorzbb <zbb@FreeBSD.org>2017-06-20 11:11:42 +0000
committerLuiz Souza <luiz@netgate.com>2017-09-06 13:45:06 -0500
commit4720534d16dec2312520ee2f2430aff2ac2bc3d7 (patch)
tree02e53a414670fa7194d483d9376fe4eb81d0b1a6 /sys/arm/arm
parent4dfd2a820d8dac06559f5417c744fbe6f7710c79 (diff)
downloadFreeBSD-src-4720534d16dec2312520ee2f2430aff2ac2bc3d7.zip
FreeBSD-src-4720534d16dec2312520ee2f2430aff2ac2bc3d7.tar.gz
Disable PL310 outer cache sync for IO coherent platforms
When a PL310 cache is used on a system that provides hardware coherency, the outer cache sync operation is useless, and can be skipped. Moreover, on some systems, it is harmful as it causes deadlocks between the Marvell coherency mechanism, the Marvell PCIe or Crypto controllers and the Cortex-A9. To avoid this, this commit introduces a new Device Tree property 'arm,io-coherent' for the L2 cache controller node, valid only for the PL310 cache. It identifies the usage of the PL310 cache in an I/O coherent configuration. Internally, it makes the driver disable the outer cache sync operation. Note, that other outer-cache operations are not removed, as they may be needed for certain situations, such as booting secondary CPUs. Moreover, in order to enable IO coherent operation, the decision whether to use L2 cache maintenance callbacks is done in busdma layer, which was enabled in one of the previous commits. Submitted by: Michal Mazur <mkm@semihalf.com> Marcin Wojtas <mw@semihalf.com> Reviewed by: mmel Obtained from: Semihalf Differential revision: https://reviews.freebsd.org/D11245 (cherry picked from commit d4d94445f1fd0de66e64fd589865b027eab17726)
Diffstat (limited to 'sys/arm/arm')
-rw-r--r--sys/arm/arm/pl310.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/sys/arm/arm/pl310.c b/sys/arm/arm/pl310.c
index c269b47..3ccace3 100644
--- a/sys/arm/arm/pl310.c
+++ b/sys/arm/arm/pl310.c
@@ -207,6 +207,10 @@ pl310_cache_sync(void)
if ((pl310_softc == NULL) || !pl310_softc->sc_enabled)
return;
+ /* Do not sync outer cache on IO coherent platform */
+ if (pl310_softc->sc_io_coherent)
+ return;
+
#ifdef PL310_ERRATA_753970
if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
/* Write uncached PL310 register */
@@ -441,6 +445,7 @@ pl310_attach(device_t dev)
struct pl310_softc *sc = device_get_softc(dev);
int rid;
uint32_t cache_id, debug_ctrl;
+ phandle_t node;
sc->sc_dev = dev;
rid = 0;
@@ -468,6 +473,15 @@ pl310_attach(device_t dev)
(cache_id >> CACHE_ID_RELEASE_SHIFT) & CACHE_ID_RELEASE_MASK);
/*
+ * Test for "arm,io-coherent" property and disable sync operation if
+ * platform is I/O coherent. Outer sync operations are not needed
+ * on coherent platform and may be harmful in certain situations.
+ */
+ node = ofw_bus_get_node(dev);
+ if (OF_hasprop(node, "arm,io-coherent"))
+ sc->sc_io_coherent = true;
+
+ /*
* If L2 cache is already enabled then something has violated the rules,
* because caches are supposed to be off at kernel entry. The cache
* must be disabled to write the configuration registers without
OpenPOWER on IntegriCloud