Index: sys/arm/arm/pl310.c =================================================================== --- sys/arm/arm/pl310.c +++ sys/arm/arm/pl310.c @@ -206,6 +206,10 @@ 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 */ @@ -444,6 +448,7 @@ 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; @@ -471,6 +476,18 @@ (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. + */ + sc->sc_io_coherent = false; + if ((node = OF_finddevice("/")) > 0) { + node = ofw_bus_find_compatible(node, "arm,pl310-cache"); + if ((node > 0) && 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 Index: sys/arm/include/pl310.h =================================================================== --- sys/arm/include/pl310.h +++ sys/arm/include/pl310.h @@ -148,6 +148,7 @@ struct mtx sc_mtx; u_int sc_rtl_revision; struct intr_config_hook *sc_ich; + boolean_t sc_io_coherent; }; /**