ARM platforms that have cache-coherent peripherals should select OF_DMA_COHERENCY. These same platforms may run into issues if kernel DT is changed to assume cache coherency, while barebox DT wasn't. Therefore add a fixup that fixes up barebox dma-coherent setting into the kernel's. That way we only have to make sure that Linux and barebox are in-sync regarding CONFIG_ARCH_DMA_DEFAULT_COHERENT. Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> --- v1 -> v2: - split from Layerscape support and make it generic to all users of CONFIG_OF_DMA_COHERENCY - fixup both dma-coherent or dma-noncoherent if needed - don't fix up new property of coherency setting is the default --- drivers/dma/Kconfig | 5 ++++- drivers/dma/Makefile | 1 + drivers/dma/of_fixups.c | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 drivers/dma/of_fixups.c diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 635b11c7af7d..e7516466d9d3 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -15,6 +15,9 @@ config OF_DMA_COHERENCY For most platforms supported, either all DMA is coherent or it isn't. Platforms that have DMA masters of mixed coherency or that differ from the architecture default will select this option to parse - DMA coherency out of the DT. + DMA coherency out of the DT. This allows barebox to choose the + correct cache maintenance operation during runtime and will cause + barebox to fix up its own DMA coherency setting into the kernel + DT if it differs. endmenu diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index b55c16e768d5..77bd8abba52c 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_HAS_DMA) += map.o obj-$(CONFIG_DMA_API_DEBUG) += debug.o obj-$(CONFIG_MXS_APBH_DMA) += apbh_dma.o +obj-$(CONFIG_OF_DMA_COHERENCY) += of_fixups.o diff --git a/drivers/dma/of_fixups.c b/drivers/dma/of_fixups.c new file mode 100644 index 000000000000..668313bbfb57 --- /dev/null +++ b/drivers/dma/of_fixups.c @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <of.h> +#include <of_address.h> +#include <driver.h> + +static int of_dma_coherent_fixup(struct device_node *root, void *data) +{ + struct device_node *soc; + enum dev_dma_coherence coherency = (enum dev_dma_coherence)(uintptr_t)data; + + soc = of_find_node_by_path_from(root, "/soc"); + if (!soc) + return -ENOENT; + + of_property_write_bool(soc, "dma-noncoherent", coherency == DEV_DMA_NON_COHERENT); + of_property_write_bool(soc, "dma-coherent", coherency == DEV_DMA_COHERENT); + + return 0; +} + +static int of_dma_coherent_fixup_register(void) +{ + struct device_node *soc; + enum dev_dma_coherence soc_dma_coherency; + + soc = of_find_node_by_path("/soc"); + if (!soc) + return -ENOENT; + + if (of_property_read_bool(soc, "dma-coherent")) + soc_dma_coherency = DEV_DMA_COHERENT; + else if (of_property_read_bool(soc, "dma-noncoherent")) + soc_dma_coherency = DEV_DMA_NON_COHERENT; + else + soc_dma_coherency = DEV_DMA_COHERENCE_DEFAULT; + + return of_register_fixup(of_dma_coherent_fixup, (void *)(uintptr_t)soc_dma_coherency); +} +coredevice_initcall(of_dma_coherent_fixup_register); -- 2.39.2