From 53d224abf0b034d91faf5b0c410cada40c65234b Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Mon, 5 Jun 2023 16:28:07 +0200 Subject: Fix DMA configuration in NPU Linux kernel driver Currently, when the NPU driver allocates buffers for the NPU subsystem, it does not provide DMA addresses that can be used by the subsystem. Instead, the DMA address is set to the Linux Kernel physical address and must be translated by the firmware before use. The correct DMA address is not provided because the device instance created by the NPU driver has not been DMA configured so it does not know about the subsystem's address requirements. To resolve this, the device will now inherit the DMA configuration from the parent rproc device. Change-Id: Ibcbf30e812e72ebf8672bbe9dde3a9f9abdaa417 Signed-off-by: Mikael Olsson --- kernel/ethosu_device.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/kernel/ethosu_device.c b/kernel/ethosu_device.c index b889a7b..83df62e 100644 --- a/kernel/ethosu_device.c +++ b/kernel/ethosu_device.c @@ -1,5 +1,6 @@ /* - * Copyright 2020-2023 Arm Limited and/or its affiliates + * SPDX-FileCopyrightText: Copyright 2020-2023 Arm Limited and/or its affiliates + * SPDX-License-Identifier: GPL-2.0-only * * This program is free software and is provided to you under the terms of the * GNU General Public License version 2 as published by the Free Software @@ -14,8 +15,6 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, you can access it online at * http://www.gnu.org/licenses/gpl-2.0.html. - * - * SPDX-License-Identifier: GPL-2.0-only */ /**************************************************************************** @@ -38,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -50,8 +50,6 @@ #define MINOR_BASE 0 /* Minor version starts at 0 */ #define MINOR_COUNT 64 /* Allocate minor versions */ -#define DMA_ADDR_BITS 32 /* Number of address bits */ - /**************************************************************************** * Variables ****************************************************************************/ @@ -402,20 +400,30 @@ static int ethosu_device_register(struct device *dev, return ret; } - /* Inherit DMA settings for rproc device */ - ret = of_reserved_mem_device_init_by_idx(dev, - rproc->dev.parent->of_node, 0); + /* Inherit DMA mask from rproc device */ + ret = dma_coerce_mask_and_coherent(dev, + dma_get_mask(rproc->dev.parent)); if (ret) { - dev_err(parent, "Failed to initialize reserved memory. ret=%d", + dev_err(parent, "Failed to set DMA mask. ret=%d", ret); + + return ret; + } + + /* Inherit DMA configuration from rproc device */ + ret = of_dma_configure(dev, rproc->dev.parent->of_node, false); + if (ret) { + dev_err(parent, "Failed to configure DMA. ret=%d", ret); return ret; } - /* Set mask for coherent DMA addressing */ - ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(DMA_ADDR_BITS)); + /* Inherit reserved memory from rproc device */ + ret = of_reserved_mem_device_init_by_idx(dev, + rproc->dev.parent->of_node, 0); if (ret) { - dev_err(parent, "Failed to set coherent DMA mask. ret=%d", ret); + dev_err(parent, "Failed to initialize reserved memory. ret=%d", + ret); return ret; } -- cgit v1.2.1