All of lore.kernel.org
 help / color / mirror / Atom feed
From: Masahiro Yamada <yamada.masahiro@socionext.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 3/3] sysreset: psci: support system reset in a generic way with PSCI
Date: Thu, 13 Apr 2017 11:39:13 +0900	[thread overview]
Message-ID: <1492051153-12817-4-git-send-email-yamada.masahiro@socionext.com> (raw)
In-Reply-To: <1492051153-12817-1-git-send-email-yamada.masahiro@socionext.com>

If the system is running PSCI firmware, the System Reset function
(func ID: 0x80000009) is supposed to be handled by PSCI, that is,
the SoC/board specific reset implementation should be moved to PSCI.
U-Boot should call the PSCI service according to the arm-smccc
manner.

The arm-smccc is supported on ARMv7 or later.  Especially, ARMv8
generation SoCs are likely to run ARM Trusted Firmware BL31.  In
this case, U-Boot is a non-secure world boot loader, so it should
not be able to reset the system directly.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v2: None

 arch/arm/Kconfig                   |  1 +
 drivers/Kconfig                    |  2 +
 drivers/Makefile                   |  5 +-
 drivers/firmware/Kconfig           |  6 +++
 drivers/firmware/Makefile          |  2 +
 drivers/firmware/firmware-uclass.c | 11 +++++
 drivers/firmware/psci.c            | 94 ++++++++++++++++++++++++++++++++++++++
 drivers/sysreset/Kconfig           | 10 ++++
 drivers/sysreset/Makefile          |  1 +
 drivers/sysreset/sysreset_psci.c   | 41 +++++++++++++++++
 include/dm/uclass-id.h             |  1 +
 include/linux/psci.h               | 13 ++++++
 12 files changed, 185 insertions(+), 2 deletions(-)
 create mode 100644 drivers/firmware/Kconfig
 create mode 100644 drivers/firmware/Makefile
 create mode 100644 drivers/firmware/firmware-uclass.c
 create mode 100644 drivers/firmware/psci.c
 create mode 100644 drivers/sysreset/sysreset_psci.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 84744ef..64984dc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -177,6 +177,7 @@ config SYS_CACHELINE_SIZE
 config ARM_SMCCC
 	bool "Support for ARM SMC Calling Convention (SMCCC)"
 	depends on CPU_V7 || ARM64
+	select ARM_PSCI_FW
 	help
 	  Say Y here if you want to enable ARM SMC Calling Convention.
 	  This should be enabled if U-Boot needs to communicate with system
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 0e5d97d..d0a36ab 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -22,6 +22,8 @@ source "drivers/dfu/Kconfig"
 
 source "drivers/dma/Kconfig"
 
+source "drivers/firmware/Kconfig"
+
 source "drivers/fpga/Kconfig"
 
 source "drivers/gpio/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 5d8baa5..4a4b237 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -23,7 +23,7 @@ obj-$(CONFIG_SPL_SERIAL_SUPPORT) += serial/
 obj-$(CONFIG_SPL_SPI_SUPPORT) += spi/
 obj-$(CONFIG_SPL_POWER_SUPPORT) += power/ power/pmic/
 obj-$(CONFIG_SPL_POWER_SUPPORT) += power/regulator/
-obj-$(CONFIG_SPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/
+obj-$(CONFIG_SPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/ firmware/
 obj-$(CONFIG_SPL_MTD_SUPPORT) += mtd/
 obj-$(CONFIG_SPL_NAND_SUPPORT) += mtd/nand/
 obj-$(CONFIG_SPL_ONENAND_SUPPORT) += mtd/onenand/
@@ -52,7 +52,7 @@ endif
 ifdef CONFIG_TPL_BUILD
 
 obj-$(CONFIG_TPL_I2C_SUPPORT) += i2c/
-obj-$(CONFIG_TPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/
+obj-$(CONFIG_TPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/ firmware/
 obj-$(CONFIG_TPL_MMC_SUPPORT) += mmc/
 obj-$(CONFIG_TPL_MPC8XXX_INIT_DDR_SUPPORT) += ddr/fsl/
 obj-$(CONFIG_TPL_NAND_SUPPORT) += mtd/nand/
@@ -71,6 +71,7 @@ obj-y += block/
 obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/
 obj-$(CONFIG_CPU) += cpu/
 obj-y += crypto/
+obj-y += firmware/
 obj-$(CONFIG_FPGA) += fpga/
 obj-y += hwmon/
 obj-y += misc/
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
new file mode 100644
index 0000000..4c32426
--- /dev/null
+++ b/drivers/firmware/Kconfig
@@ -0,0 +1,6 @@
+config FIRMWARE
+	bool
+
+config ARM_PSCI_FW
+	bool
+	select FIRMWARE
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
new file mode 100644
index 0000000..b208255
--- /dev/null
+++ b/drivers/firmware/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_FIRMWARE)		+= firmware-uclass.o
+obj-$(CONFIG_ARM_PSCI_FW)	+= psci.o
diff --git a/drivers/firmware/firmware-uclass.c b/drivers/firmware/firmware-uclass.c
new file mode 100644
index 0000000..01b6a44
--- /dev/null
+++ b/drivers/firmware/firmware-uclass.c
@@ -0,0 +1,11 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <dm/uclass.h>
+
+/* Firmware access is platform-dependent.  No generic code in uclass */
+UCLASS_DRIVER(firmware) = {
+	.id		= UCLASS_FIRMWARE,
+	.name		= "firmware",
+};
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
new file mode 100644
index 0000000..40fba64
--- /dev/null
+++ b/drivers/firmware/psci.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * Based on drivers/firmware/psci.c from Linux:
+ * Copyright (C) 2015 ARM Limited
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm/device.h>
+#include <dm/lists.h>
+#include <libfdt.h>
+#include <linux/arm-smccc.h>
+#include <linux/errno.h>
+#include <linux/psci.h>
+
+psci_fn *invoke_psci_fn;
+
+static unsigned long __invoke_psci_fn_hvc(unsigned long function_id,
+			unsigned long arg0, unsigned long arg1,
+			unsigned long arg2)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_hvc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+	return res.a0;
+}
+
+static unsigned long __invoke_psci_fn_smc(unsigned long function_id,
+			unsigned long arg0, unsigned long arg1,
+			unsigned long arg2)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+	return res.a0;
+}
+
+static int psci_bind(struct udevice *dev)
+{
+	/* No SYSTEM_RESET support for PSCI 0.1 */
+	if (of_device_is_compatible(dev, "arm,psci-0.2") ||
+	    of_device_is_compatible(dev, "arm,psci-1.0")) {
+		int ret;
+
+		/* bind psci-sysreset optionally */
+		ret = device_bind_driver(dev, "psci-sysreset", "psci-sysreset",
+					 NULL);
+		if (ret)
+			debug("PSCI System Reset was not bound.\n");
+	}
+
+	return 0;
+}
+
+static int psci_probe(struct udevice *dev)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	const char *method;
+
+	method = fdt_stringlist_get(gd->fdt_blob, dev->of_offset, "method", 0,
+				    NULL);
+	if (!method) {
+		printf("missing \"method\" property\n");
+		return -ENXIO;
+	}
+
+	if (!strcmp("hvc", method)) {
+		invoke_psci_fn = __invoke_psci_fn_hvc;
+	} else if (!strcmp("smc", method)) {
+		invoke_psci_fn = __invoke_psci_fn_smc;
+	} else {
+		printf("invalid \"method\" property: %s\n", method);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id psci_of_match[] = {
+	{ .compatible = "arm,psci" },
+	{ .compatible = "arm,psci-0.2" },
+	{ .compatible = "arm,psci-1.0" },
+	{},
+};
+
+U_BOOT_DRIVER(psci) = {
+	.name = "psci",
+	.id = UCLASS_FIRMWARE,
+	.of_match = psci_of_match,
+	.bind = psci_bind,
+	.probe = psci_probe,
+};
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index 05a37b9..9664630 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -13,4 +13,14 @@ config SYSRESET
 	  to effect a reset. The uclass will try all available drivers when
 	  reset_walk() is called.
 
+if SYSRESET
+
+config SYSRESET_PSCI
+	bool "Enable support for PSCI System Reset"
+	depends on ARM_PSCI_FW
+	help
+	  Enable PSCI SYSTEM_RESET function call.  To use this, PSCI firmware
+	  must be running on your system.
+
+endif
 endmenu
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index 49b8bb6..7bb8406 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -5,6 +5,7 @@
 #
 
 obj-$(CONFIG_SYSRESET) += sysreset-uclass.o
+obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
 
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_ROCKCHIP_RK3036) += sysreset_rk3036.o
diff --git a/drivers/sysreset/sysreset_psci.c b/drivers/sysreset/sysreset_psci.c
new file mode 100644
index 0000000..a4911b7
--- /dev/null
+++ b/drivers/sysreset/sysreset_psci.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <dm/device.h>
+#include <sysreset.h>
+#include <linux/errno.h>
+#include <linux/psci.h>
+
+static int psci_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+	unsigned long function_id;
+
+	switch (type) {
+	case SYSRESET_WARM:
+	case SYSRESET_COLD:
+		function_id = PSCI_0_2_FN_SYSTEM_RESET;
+		break;
+	case SYSRESET_POWER:
+		function_id = PSCI_0_2_FN_SYSTEM_OFF;
+		break;
+	default:
+		return -ENOSYS;
+	}
+
+	invoke_psci_fn(function_id, 0, 0, 0);
+
+	return -EINPROGRESS;
+}
+
+static struct sysreset_ops psci_sysreset_ops = {
+	.request = psci_sysreset_request,
+};
+
+U_BOOT_DRIVER(psci_sysreset) = {
+	.name = "psci-sysreset",
+	.id = UCLASS_SYSRESET,
+	.ops = &psci_sysreset_ops,
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 8c92d0b..1b635e4 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -35,6 +35,7 @@ enum uclass_id {
 	UCLASS_DMA,		/* Direct Memory Access */
 	UCLASS_ETH,		/* Ethernet device */
 	UCLASS_GPIO,		/* Bank of general-purpose I/O pins */
+	UCLASS_FIRMWARE,	/* Firmware */
 	UCLASS_I2C,		/* I2C bus */
 	UCLASS_I2C_EEPROM,	/* I2C EEPROM device */
 	UCLASS_I2C_GENERIC,	/* Generic I2C device */
diff --git a/include/linux/psci.h b/include/linux/psci.h
index 310d83e..8d13bd2 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -87,4 +87,17 @@
 #define PSCI_RET_NOT_PRESENT			-7
 #define PSCI_RET_DISABLED			-8
 
+#ifdef CONFIG_ARM_PSCI_FW
+typedef unsigned long (psci_fn)(unsigned long, unsigned long,
+				unsigned long, unsigned long);
+
+extern psci_fn *invoke_psci_fn;
+#else
+unsigned long invoke_psci_fn(unsigned long a0, unsigned long a1,
+			     unsigned long a2, unsigned long a3)
+{
+	return PSCI_RET_DISABLED;
+}
+#endif
+
 #endif /* _UAPI_LINUX_PSCI_H */
-- 
2.7.4

  parent reply	other threads:[~2017-04-13  2:39 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-13  2:39 [U-Boot] [PATCH v2 0/3] ARM: support System Reset via PSCI Masahiro Yamada
2017-04-13  2:39 ` [U-Boot] [PATCH v2 1/3] ARM: import arm-smccc code from Linux 4.11-rc6 Masahiro Yamada
2017-04-13  2:39 ` [U-Boot] [PATCH v2 2/3] ARM: adjust arm-smccc code for use in U-Boot Masahiro Yamada
2017-04-13 13:57   ` Masahiro Yamada
2017-04-13  2:39 ` Masahiro Yamada [this message]
2017-04-16 19:31   ` [U-Boot] [PATCH v2 3/3] sysreset: psci: support system reset in a generic way with PSCI Simon Glass
2017-04-17  2:26     ` Masahiro Yamada

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1492051153-12817-4-git-send-email-yamada.masahiro@socionext.com \
    --to=yamada.masahiro@socionext.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.