summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/arm/arm/pl310.c14
-rw-r--r--sys/arm/include/pl310.h1
2 files changed, 15 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
diff --git a/sys/arm/include/pl310.h b/sys/arm/include/pl310.h
index 5fcb7af..6160135 100644
--- a/sys/arm/include/pl310.h
+++ b/sys/arm/include/pl310.h
@@ -148,6 +148,7 @@ struct pl310_softc {
struct mtx sc_mtx;
u_int sc_rtl_revision;
struct intr_config_hook *sc_ich;
+ boolean_t sc_io_coherent;
};
/**
OpenPOWER on IntegriCloud