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 <mikael.olsson@arm.com>
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 <open-source-office@arm.com>
+ * 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 <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/io.h>
+#include <linux/of_device.h>
 #include <linux/of_reserved_mem.h>
 #include <linux/remoteproc.h>
 #include <linux/slab.h>
@@ -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 @@
 		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;
 	}