Implement reset handler for remoteproc

Use the reset controller driver mechanism to control the Ethos-U
subsystem remoteproc driver.

Change-Id: If180d5b922f8b1cd245af7f922911c17ecd313a3
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fc2b91f..4711a19 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2020 Arm Limited. All rights reserved.
+# Copyright (c) 2020-2021 Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: Apache-2.0
 #
@@ -24,6 +24,7 @@
 # Default options
 option(BUILD_KERNEL "Build the kernel driver" ON)
 option(BUILD_MAILBOX "Build the MHU mailbox kernel module" ON)
+option(BUILD_REMOTEPROC "Build the remoteproc kernel module" ON)
 
 # Add rpath to library directory
 set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
@@ -40,6 +41,10 @@
     add_subdirectory(mailbox)
 endif()
 
+if (BUILD_REMOTEPROC)
+add_subdirectory(remoteproc)
+endif()
+
 # Build flatbuffers
 unset(PROJECT_VERSION)
 unset(PROJECT_VERSION_MAJOR)
diff --git a/remoteproc/.clang-format b/remoteproc/.clang-format
new file mode 100644
index 0000000..fef91a6
--- /dev/null
+++ b/remoteproc/.clang-format
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2019-2021 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the License); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an AS IS BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+---
+Language: Cpp
+SortIncludes: false
+DisableFormat: true
+---
diff --git a/remoteproc/.gitignore b/remoteproc/.gitignore
new file mode 100644
index 0000000..6eaa333
--- /dev/null
+++ b/remoteproc/.gitignore
@@ -0,0 +1,28 @@
+#
+# Copyright (c) 2020-2021 Arm Limited. All rights reserved.
+#
+# 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
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# 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
+#
+
+Module.symvers
+modules.order
+*.cmd
+*.mod.*
+*.o
+*.ko
+.*.swp
+.tmp_versions
diff --git a/remoteproc/CMakeLists.txt b/remoteproc/CMakeLists.txt
new file mode 100644
index 0000000..9c88df1
--- /dev/null
+++ b/remoteproc/CMakeLists.txt
@@ -0,0 +1,54 @@
+#
+# Copyright (c) 2020-2021 Arm Limited. All rights reserved.
+#
+# 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
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# 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
+#
+
+cmake_minimum_required(VERSION 3.0.2)
+
+# Set the project name and version
+project("ethosu_remoteproc" VERSION 1.0)
+
+# Make sure KDIR is set
+set(KDIR "" CACHE PATH "Path to Linux kernel sources")
+if (NOT EXISTS ${KDIR})
+    message(FATAL_ERROR "Can't build kernel module without KDIR.")
+endif()
+
+# Depend on all h and c files
+file(GLOB_RECURSE SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c" "*.h")
+
+file(GLOB_RECURSE OBJ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c")
+list(TRANSFORM OBJ REPLACE "^(.*)[.]c" "\\1.o")
+list(TRANSFORM OBJ PREPEND ${CMAKE_CURRENT_SOURCE_DIR}/)
+
+# Build the kernel module
+add_custom_target(ethosu-remoteproc-module ALL
+    COMMAND ${CMAKE_MAKE_PROGRAM} -C ${KDIR}
+    EXTRA_CFLAGS=-I${KDIR}/../../../drivers/remoteproc M=${CMAKE_CURRENT_SOURCE_DIR}
+                  CONFIG_ETHOSU_RESET=m
+                  CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 modules
+                  BYPRODUCTS
+                  ${CMAKE_CURRENT_SOURCE_DIR}/ethosu_remoteproc.ko
+                  ${CMAKE_CURRENT_SOURCE_DIR}/ethosu_remoteproc.mod.o
+                  ${CMAKE_CURRENT_SOURCE_DIR}/modules.order
+                  ${CMAKE_CURRENT_SOURCE_DIR}/Module.symvers
+                  ${OBJ}
+                  DEPENDS ${SOURCES} Kbuild Kconfig
+                  COMMENT "Building ethosu_remoteproc.ko"
+                  VERBATIM)
+
diff --git a/remoteproc/Kbuild b/remoteproc/Kbuild
new file mode 100644
index 0000000..1f02245
--- /dev/null
+++ b/remoteproc/Kbuild
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2020-2021 Arm Limited. All rights reserved.
+#
+# 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
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# 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
+#
+
+obj-$(CONFIG_ETHOSU_RESET) += ethosu_bridge_reset.o
diff --git a/remoteproc/Kconfig b/remoteproc/Kconfig
new file mode 100644
index 0000000..4884cd2
--- /dev/null
+++ b/remoteproc/Kconfig
@@ -0,0 +1,28 @@
+#
+# Copyright (c) 2020-2021 Arm Limited. All rights reserved.
+#
+# 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
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# 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
+#
+
+config ARM_ETHOSU_SGM775_RESET
+	tristate "Arm Ethos-U SGM775 Reset"
+	depends on RESET_CONTROLLER
+        help
+          Say Y here if you want to build the Arm Ethos-U reset controller
+          reference module for controlling the reset of Cortex-M CPU on
+          the Ethos-U subsystem.
+
diff --git a/remoteproc/ethosu_bridge_reset.c b/remoteproc/ethosu_bridge_reset.c
new file mode 100644
index 0000000..7f73ee7
--- /dev/null
+++ b/remoteproc/ethosu_bridge_reset.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2021 Arm Limited. All rights reserved.
+ *
+ * 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
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+
+#define ETHOSU_BRIDGE_RESET_DRIVER_VERSION "0.0.1"
+
+struct ethosu_reset {
+	struct reset_controller_dev rst;
+	struct device               *dev;
+	void __iomem                *base;
+};
+
+#define ETHOSU_BRIDGE_ID(base)   (base)
+#define ETHOSU_BRIDGE_CTRL(base) ((base) + 0x100)
+
+#define ETHOSU_BRIDGE_WAIT_ENABLE (0x2)
+#define ETHOSU_BRIDGE_RESET       (0x1)
+
+static void __iomem *bridge_verify_and_remap(struct device *dev,
+					     struct resource *res)
+{
+	void __iomem *base = devm_ioremap_resource(dev, res);
+	u32 id;
+	u16 magic;
+	u8 minor;
+	u8 major;
+
+	if (IS_ERR(base))
+		return base;
+
+	id = readl(ETHOSU_BRIDGE_ID(base));
+	magic = id & 0x0000ffff;
+	minor = (id & 0x00ff0000) >> 16;
+	major = (id & 0xff000000) >> 24;
+
+	dev_dbg(dev, "verifying bridge %d.%d", major, minor);
+
+	if (magic != 0xBD9E)
+		return IOMEM_ERR_PTR(-EINVAL);
+
+	return base;
+}
+
+int ethosu_bridge_assert(struct reset_controller_dev *rcdev,
+			 unsigned long id)
+{
+	struct ethosu_reset *ethosu = container_of(rcdev, struct ethosu_reset,
+						   rst);
+
+	/* pull reset */
+	dev_dbg(ethosu->dev, "Asserting reset");
+
+	/* set wait and reset */
+	writel(ETHOSU_BRIDGE_WAIT_ENABLE | ETHOSU_BRIDGE_RESET,
+	       ETHOSU_BRIDGE_CTRL(ethosu->base));
+
+	return 0;
+}
+
+int ethosu_bridge_deassert(struct reset_controller_dev *rcdev,
+			   unsigned long id)
+{
+	struct ethosu_reset *ethosu = container_of(rcdev, struct ethosu_reset,
+						   rst);
+
+	/* release reset */
+	dev_dbg(ethosu->dev, "Deasserting reset");
+	writel(~ETHOSU_BRIDGE_WAIT_ENABLE & ETHOSU_BRIDGE_RESET,
+	       ETHOSU_BRIDGE_CTRL(ethosu->base));
+
+	return 0;
+}
+
+static struct reset_control_ops ethosu_reset_bridge_ops = {
+	.assert   = ethosu_bridge_assert,
+	.deassert = ethosu_bridge_deassert,
+};
+
+static const struct of_device_id ethosu_reset_match[] = {
+	{ .compatible = "arm,ethosu-bridge-reset", .data = 0 },
+	{ /* sentinel */ },
+};
+
+static int ethosu_bridge_reset_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct ethosu_reset *ethosu;
+	struct resource *res;
+
+	ethosu = devm_kzalloc(&pdev->dev, sizeof(*ethosu), GFP_KERNEL);
+	if (!ethosu)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	ethosu->base = bridge_verify_and_remap(dev, res);
+	ethosu->dev = dev;
+
+	if (IS_ERR(ethosu->base))
+		return PTR_ERR(ethosu->base);
+
+	platform_set_drvdata(pdev, ethosu);
+
+	ethosu->rst.owner = THIS_MODULE;
+	ethosu->rst.nr_resets = 1;
+	ethosu->rst.ops = &ethosu_reset_bridge_ops;
+	ethosu->rst.of_node = pdev->dev.of_node;
+
+	dev_dbg(dev, "registering to reset controller core");
+
+	return devm_reset_controller_register(dev, &ethosu->rst);
+}
+
+static int ethosu_bridge_reset_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static struct platform_driver ethosu_reset_driver = {
+	.probe                  = ethosu_bridge_reset_probe,
+	.remove                 = ethosu_bridge_reset_remove,
+	.driver                 = {
+		.name           = "ethosu-bridge-reset",
+		.of_match_table = of_match_ptr(ethosu_reset_match),
+	},
+};
+
+module_platform_driver(ethosu_reset_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Arm Ltd");
+MODULE_DESCRIPTION("Arm Ethos-U NPU Bridge Reset Driver");
+MODULE_VERSION(ETHOSU_BRIDGE_RESET_DRIVER_VERSION);
diff --git a/remoteproc/remoteproc.dtsi b/remoteproc/remoteproc.dtsi
new file mode 100644
index 0000000..9f1a21c
--- /dev/null
+++ b/remoteproc/remoteproc.dtsi
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021 Arm Limited. All rights reserved.
+ *
+ * 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
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+
+
+/{
+    /* Example for using reset driver dts entries for Ethos-U */
+    ethosu_reset: sgm775_ethosu_bridge@0x500f0000 {
+            compatible ="arm,ethosu-bridge-reset";
+            #reset-cells = <1>;
+            reg = <0x0 0x500f0000 0x0 0x00001000>;
+    };
+
+};
+