Index: sys/arm/arm/pl310.c =================================================================== --- sys/arm/arm/pl310.c +++ sys/arm/arm/pl310.c @@ -529,7 +529,8 @@ cpufuncs.cf_l2cache_wbinv_range = pl310_wbinv_range; cpufuncs.cf_l2cache_inv_range = pl310_inv_range; cpufuncs.cf_l2cache_wb_range = pl310_wb_range; - cpufuncs.cf_l2cache_drain_writebuf = pl310_drain_writebuf; + if (cpufuncs.cf_l2cache_drain_writebuf == cpufunc_nullop) + cpufuncs.cf_l2cache_drain_writebuf = pl310_drain_writebuf; return (0); } Index: sys/arm/mv/mv_common.c =================================================================== --- sys/arm/mv/mv_common.c +++ sys/arm/mv/mv_common.c @@ -115,6 +115,8 @@ static void decode_win_sdhci_dump(u_long); static void decode_win_pcie_dump(u_long); +static void l2cache_drainwb_coherent(void); + static int fdt_get_ranges(const char *, void *, int, int *, int *); #ifdef SOC_MV_ARMADA38X int gic_decode_fdt(phandle_t iparent, pcell_t *intr, int *interrupt, @@ -128,6 +130,7 @@ static int cpu_wins_no = 0; static int eth_port = 0; static int usb_port = 0; +static boolean_t plat_dma_coherent = false; static struct decode_win cpu_win_tbl[MAX_CPU_WIN]; @@ -568,11 +571,17 @@ SYSINIT(mv_enter_debugger, SI_SUB_CPU, SI_ORDER_ANY, mv_enter_debugger, NULL); #endif +static void l2cache_drainwb_coherent(void) +{ + /* No-op for coherent platforms */ +} + int soc_decode_win(void) { uint32_t dev, rev; int mask, err; + phandle_t node; mask = 0; TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask); @@ -587,6 +596,13 @@ /* Retrieve our ID: some windows facilities vary between SoC models */ soc_id(&dev, &rev); + /* Retrieve information about DMA coherency from device tree */ + node = OF_finddevice("/soc"); + if ((node > 0) && OF_hasprop(node, "dma-coherent")) { + plat_dma_coherent = true; + cpufuncs.cf_l2cache_drain_writebuf = l2cache_drainwb_coherent; + } + #ifdef SOC_MV_ARMADAXP if ((err = decode_win_sdram_fixup()) != 0) return(err); @@ -1064,7 +1080,7 @@ uint32_t ddr_attr(int i) { - uint32_t dev, rev; + uint32_t dev, rev, attr; soc_id(&dev, &rev); if (dev == MV_DEV_88RC8180) @@ -1072,10 +1088,14 @@ if (dev == MV_DEV_88F6781) return (0); - return (i == 0 ? 0xe : + attr = (i == 0 ? 0xe : (i == 1 ? 0xd : (i == 2 ? 0xb : (i == 3 ? 0x7 : 0xff)))); + if (plat_dma_coherent) + attr |= 0x10; + + return (attr); } uint32_t