diff options
-rw-r--r-- | sys/arm/arm/pl310.c | 14 | ||||
-rw-r--r-- | sys/arm/include/pl310.h | 1 |
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; }; /** |