* [PATCH v4 2/8] firmware: scmi: mailbox/smt agent device
2020-09-09 16:44 [PATCH v4 1/8] firmware: add SCMI agent uclass Etienne Carriere
@ 2020-09-09 16:44 ` Etienne Carriere
2020-09-10 13:38 ` Simon Glass
2020-10-01 14:07 ` Tom Rini
2020-09-09 16:44 ` [PATCH v4 3/8] firmware: scmi: support Arm SMCCC transport Etienne Carriere
` (6 subsequent siblings)
7 siblings, 2 replies; 23+ messages in thread
From: Etienne Carriere @ 2020-09-09 16:44 UTC (permalink / raw)
To: u-boot
This change implements a mailbox transport using SMT format for SCMI
exchanges. This implementation follows the Linux kernel and
SCP-firmware [1] as references implementation for SCMI message
processing using SMT format for communication channel meta-data.
Use of mailboxes in SCMI FDT bindings are defined in the Linux kernel
DT bindings since v4.17.
Links: [1] https://github.com/ARM-software/SCP-firmware
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Cc: Simon Glass <sjg@chromium.org>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
---
Changes in v4:
- Replace __arm__ with CONFIG_ARM.
- Remove cast for priv reference hence remove helper scmi_mbox_get_priv().
Changes in v3:
- This is a followup of the SCMI agent patches posted in
https://patchwork.ozlabs.org/project/uboot/list/?series=196253
The v3 splits commits and introduces a new uclass as requested.
- This patch implements the same mailbox SCMI agent proposed in v2
but split over few source files.
---
drivers/firmware/scmi/Kconfig | 6 +-
drivers/firmware/scmi/Makefile | 2 +
drivers/firmware/scmi/mailbox_agent.c | 102 +++++++++++++++++++
drivers/firmware/scmi/smt.c | 139 ++++++++++++++++++++++++++
drivers/firmware/scmi/smt.h | 86 ++++++++++++++++
5 files changed, 333 insertions(+), 2 deletions(-)
create mode 100644 drivers/firmware/scmi/mailbox_agent.c
create mode 100644 drivers/firmware/scmi/smt.c
create mode 100644 drivers/firmware/scmi/smt.h
diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig
index 57e2ebbe42..c501bf4943 100644
--- a/drivers/firmware/scmi/Kconfig
+++ b/drivers/firmware/scmi/Kconfig
@@ -2,7 +2,7 @@ config SCMI_FIRMWARE
bool "Enable SCMI support"
select FIRMWARE
select OF_TRANSLATE
- depends on SANDBOX
+ depends on SANDBOX || DM_MAILBOX
help
System Control and Management Interface (SCMI) is a communication
protocol that defines standard interfaces for power, performance
@@ -14,4 +14,6 @@ config SCMI_FIRMWARE
or a companion host in the CPU system.
Communications between agent (client) and the SCMI server are
- based on message exchange.
+ based on message exchange. Messages can be exchange over tranport
+ channels as a mailbox device with some piece of identified shared
+ memory.
diff --git a/drivers/firmware/scmi/Makefile b/drivers/firmware/scmi/Makefile
index 336ea1f2a3..d22f53efe7 100644
--- a/drivers/firmware/scmi/Makefile
+++ b/drivers/firmware/scmi/Makefile
@@ -1,2 +1,4 @@
obj-y += scmi_agent-uclass.o
+obj-y += smt.o
+obj-$(CONFIG_DM_MAILBOX) += mailbox_agent.o
obj-$(CONFIG_SANDBOX) += sandbox-scmi_agent.o
diff --git a/drivers/firmware/scmi/mailbox_agent.c b/drivers/firmware/scmi/mailbox_agent.c
new file mode 100644
index 0000000000..7d9fb3622e
--- /dev/null
+++ b/drivers/firmware/scmi/mailbox_agent.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Linaro Limited.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <mailbox.h>
+#include <scmi_agent.h>
+#include <scmi_agent-uclass.h>
+#include <dm/devres.h>
+#include <linux/compat.h>
+
+#include "smt.h"
+
+#define TIMEOUT_US_10MS 10000
+
+/**
+ * struct scmi_mbox_channel - Description of an SCMI mailbox transport
+ * @smt: Shared memory buffer
+ * @mbox: Mailbox channel description
+ * @timeout_us: Timeout in microseconds for the mailbox transfer
+ */
+struct scmi_mbox_channel {
+ struct scmi_smt smt;
+ struct mbox_chan mbox;
+ ulong timeout_us;
+};
+
+static int scmi_mbox_process_msg(struct udevice *dev, struct scmi_msg *msg)
+{
+ struct scmi_mbox_channel *chan = dev_get_priv(dev);
+ int ret;
+
+ ret = scmi_write_msg_to_smt(dev, &chan->smt, msg);
+ if (ret)
+ return ret;
+
+ /* Give shm addr to mbox in case it is meaningful */
+ ret = mbox_send(&chan->mbox, chan->smt.buf);
+ if (ret) {
+ dev_err(dev, "Message send failed: %d\n", ret);
+ goto out;
+ }
+
+ /* Receive the response */
+ ret = mbox_recv(&chan->mbox, chan->smt.buf, chan->timeout_us);
+ if (ret) {
+ dev_err(dev, "Response failed: %d, abort\n", ret);
+ goto out;
+ }
+
+ ret = scmi_read_resp_from_smt(dev, &chan->smt, msg);
+
+out:
+ scmi_clear_smt_channel(&chan->smt);
+
+ return ret;
+}
+
+int scmi_mbox_probe(struct udevice *dev)
+{
+ struct scmi_mbox_channel *chan = dev_get_priv(dev);
+ int ret;
+
+ chan->timeout_us = TIMEOUT_US_10MS;
+
+ ret = mbox_get_by_index(dev, 0, &chan->mbox);
+ if (ret) {
+ dev_err(dev, "Failed to find mailbox: %d\n", ret);
+ goto out;
+ }
+
+ ret = scmi_dt_get_smt_buffer(dev, &chan->smt);
+ if (ret)
+ dev_err(dev, "Failed to get shm resources: %d\n", ret);
+
+out:
+ if (ret)
+ devm_kfree(dev, chan);
+
+ return ret;
+}
+
+static const struct udevice_id scmi_mbox_ids[] = {
+ { .compatible = "arm,scmi" },
+ { }
+};
+
+static const struct scmi_agent_ops scmi_mbox_ops = {
+ .process_msg = scmi_mbox_process_msg,
+};
+
+U_BOOT_DRIVER(scmi_mbox) = {
+ .name = "scmi-over-mailbox",
+ .id = UCLASS_SCMI_AGENT,
+ .of_match = scmi_mbox_ids,
+ .priv_auto_alloc_size = sizeof(struct scmi_mbox_channel),
+ .probe = scmi_mbox_probe,
+ .ops = &scmi_mbox_ops,
+};
diff --git a/drivers/firmware/scmi/smt.c b/drivers/firmware/scmi/smt.c
new file mode 100644
index 0000000000..ce8fe49939
--- /dev/null
+++ b/drivers/firmware/scmi/smt.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (C) 2019-2020 Linaro Limited.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <dm.h>
+#include <errno.h>
+#include <scmi_agent.h>
+#include <asm/cache.h>
+#include <asm/system.h>
+#include <dm/ofnode.h>
+#include <linux/compat.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+
+#include "smt.h"
+
+/**
+ * Get shared memory configuration defined by the referred DT phandle
+ * Return with a errno compliant value.
+ */
+int scmi_dt_get_smt_buffer(struct udevice *dev, struct scmi_smt *smt)
+{
+ int ret;
+ struct ofnode_phandle_args args;
+ struct resource resource;
+ fdt32_t faddr;
+ phys_addr_t paddr;
+
+ ret = dev_read_phandle_with_args(dev, "shmem", NULL, 0, 0, &args);
+ if (ret)
+ return ret;
+
+ ret = ofnode_read_resource(args.node, 0, &resource);
+ if (ret)
+ return ret;
+
+ faddr = cpu_to_fdt32(resource.start);
+ paddr = ofnode_translate_address(args.node, &faddr);
+
+ smt->size = resource_size(&resource);
+ if (smt->size < sizeof(struct scmi_smt_header)) {
+ dev_err(dev, "Shared memory buffer too small\n");
+ return -EINVAL;
+ }
+
+ smt->buf = devm_ioremap(dev, paddr, smt->size);
+ if (!smt->buf)
+ return -ENOMEM;
+
+#ifdef CONFIG_ARM
+ if (dcache_status())
+ mmu_set_region_dcache_behaviour((uintptr_t)smt->buf,
+ smt->size, DCACHE_OFF);
+#endif
+
+ return 0;
+}
+
+/**
+ * Write SCMI message @msg into a SMT shared buffer @smt.
+ * Return 0 on success and with a negative errno in case of error.
+ */
+int scmi_write_msg_to_smt(struct udevice *dev, struct scmi_smt *smt,
+ struct scmi_msg *msg)
+{
+ struct scmi_smt_header *hdr = (void *)smt->buf;
+
+ if ((!msg->in_msg && msg->in_msg_sz) ||
+ (!msg->out_msg && msg->out_msg_sz))
+ return -EINVAL;
+
+ if (!(hdr->channel_status & SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE)) {
+ dev_dbg(dev, "Channel busy\n");
+ return -EBUSY;
+ }
+
+ if (smt->size < (sizeof(*hdr) + msg->in_msg_sz) ||
+ smt->size < (sizeof(*hdr) + msg->out_msg_sz)) {
+ dev_dbg(dev, "Buffer too small\n");
+ return -ETOOSMALL;
+ }
+
+ /* Load message in shared memory */
+ hdr->channel_status &= ~SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE;
+ hdr->length = msg->in_msg_sz + sizeof(hdr->msg_header);
+ hdr->msg_header = SMT_HEADER_TOKEN(0) |
+ SMT_HEADER_MESSAGE_TYPE(0) |
+ SMT_HEADER_PROTOCOL_ID(msg->protocol_id) |
+ SMT_HEADER_MESSAGE_ID(msg->message_id);
+
+ memcpy_toio(hdr->msg_payload, msg->in_msg, msg->in_msg_sz);
+
+ return 0;
+}
+
+/**
+ * Read SCMI message from a SMT shared buffer @smt and copy it into @msg.
+ * Return 0 on success and with a negative errno in case of error.
+ */
+int scmi_read_resp_from_smt(struct udevice *dev, struct scmi_smt *smt,
+ struct scmi_msg *msg)
+{
+ struct scmi_smt_header *hdr = (void *)smt->buf;
+
+ if (!(hdr->channel_status & SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE)) {
+ dev_err(dev, "Channel unexpectedly busy\n");
+ return -EBUSY;
+ }
+
+ if (hdr->channel_status & SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR) {
+ dev_err(dev, "Channel error reported, reset channel\n");
+ return -ECOMM;
+ }
+
+ if (hdr->length > msg->out_msg_sz + sizeof(hdr->msg_header)) {
+ dev_err(dev, "Buffer to small\n");
+ return -ETOOSMALL;
+ }
+
+ /* Get the data */
+ msg->out_msg_sz = hdr->length - sizeof(hdr->msg_header);
+ memcpy_fromio(msg->out_msg, hdr->msg_payload, msg->out_msg_sz);
+
+ return 0;
+}
+
+/**
+ * Clear SMT flags in shared buffer to allow further message exchange
+ */
+void scmi_clear_smt_channel(struct scmi_smt *smt)
+{
+ struct scmi_smt_header *hdr = (void *)smt->buf;
+
+ hdr->channel_status &= ~SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR;
+}
diff --git a/drivers/firmware/scmi/smt.h b/drivers/firmware/scmi/smt.h
new file mode 100644
index 0000000000..a8c0987bd3
--- /dev/null
+++ b/drivers/firmware/scmi/smt.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (C) 2019-2020 Linaro Limited.
+ */
+#ifndef SCMI_SMT_H
+#define SCMI_SMT_H
+
+#include <asm/types.h>
+
+/**
+ * struct scmi_smt_header - Description of the shared memory message buffer
+ *
+ * SMT stands for Shared Memory based Transport.
+ * SMT uses 28 byte header prior message payload to handle the state of
+ * the communication channel realized by the shared memory area and
+ * to define SCMI protocol information the payload relates to.
+ */
+struct scmi_smt_header {
+ __le32 reserved;
+ __le32 channel_status;
+#define SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR BIT(1)
+#define SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE BIT(0)
+ __le32 reserved1[2];
+ __le32 flags;
+#define SCMI_SHMEM_FLAG_INTR_ENABLED BIT(0)
+ __le32 length;
+ __le32 msg_header;
+ u8 msg_payload[0];
+};
+
+#define SMT_HEADER_TOKEN(token) (((token) << 18) & GENMASK(31, 18))
+#define SMT_HEADER_PROTOCOL_ID(proto) (((proto) << 10) & GENMASK(17, 10))
+#define SMT_HEADER_MESSAGE_TYPE(type) (((type) << 18) & GENMASK(9, 8))
+#define SMT_HEADER_MESSAGE_ID(id) ((id) & GENMASK(7, 0))
+
+/**
+ * struct scmi_smt - Description of a SMT memory buffer
+ * @buf: Shared memory base address
+ * @size: Shared memory byte size
+ */
+struct scmi_smt {
+ u8 *buf;
+ size_t size;
+};
+
+static inline bool scmi_smt_channel_is_free(struct scmi_smt *smt)
+{
+ struct scmi_smt_header *hdr = (void *)smt->buf;
+
+ return hdr->channel_status & SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE;
+}
+
+static inline bool scmi_smt_channel_reports_error(struct scmi_smt *smt)
+{
+ struct scmi_smt_header *hdr = (void *)smt->buf;
+
+ return hdr->channel_status & SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR;
+}
+
+static inline void scmi_smt_get_channel(struct scmi_smt *smt)
+{
+ struct scmi_smt_header *hdr = (void *)smt->buf;
+
+ hdr->channel_status &= ~SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE;
+}
+
+static inline void scmi_smt_put_channel(struct scmi_smt *smt)
+{
+ struct scmi_smt_header *hdr = (void *)smt->buf;
+
+ hdr->channel_status |= SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE;
+ hdr->channel_status &= ~SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR;
+}
+
+int scmi_dt_get_smt_buffer(struct udevice *dev, struct scmi_smt *smt);
+
+int scmi_write_msg_to_smt(struct udevice *dev, struct scmi_smt *smt,
+ struct scmi_msg *msg);
+
+int scmi_read_resp_from_smt(struct udevice *dev, struct scmi_smt *smt,
+ struct scmi_msg *msg);
+
+void scmi_clear_smt_channel(struct scmi_smt *smt);
+
+#endif /* SCMI_SMT_H */
--
2.17.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v4 2/8] firmware: scmi: mailbox/smt agent device
2020-09-09 16:44 ` [PATCH v4 2/8] firmware: scmi: mailbox/smt agent device Etienne Carriere
@ 2020-09-10 13:38 ` Simon Glass
2020-10-01 14:07 ` Tom Rini
1 sibling, 0 replies; 23+ messages in thread
From: Simon Glass @ 2020-09-10 13:38 UTC (permalink / raw)
To: u-boot
On Wed, 9 Sep 2020 at 10:44, Etienne Carriere
<etienne.carriere@linaro.org> wrote:
>
> This change implements a mailbox transport using SMT format for SCMI
> exchanges. This implementation follows the Linux kernel and
> SCP-firmware [1] as references implementation for SCMI message
> processing using SMT format for communication channel meta-data.
>
> Use of mailboxes in SCMI FDT bindings are defined in the Linux kernel
> DT bindings since v4.17.
>
> Links: [1] https://github.com/ARM-software/SCP-firmware
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> ---
>
> Changes in v4:
> - Replace __arm__ with CONFIG_ARM.
> - Remove cast for priv reference hence remove helper scmi_mbox_get_priv().
>
> Changes in v3:
> - This is a followup of the SCMI agent patches posted in
> https://patchwork.ozlabs.org/project/uboot/list/?series=196253
> The v3 splits commits and introduces a new uclass as requested.
> - This patch implements the same mailbox SCMI agent proposed in v2
> but split over few source files.
> ---
> drivers/firmware/scmi/Kconfig | 6 +-
> drivers/firmware/scmi/Makefile | 2 +
> drivers/firmware/scmi/mailbox_agent.c | 102 +++++++++++++++++++
> drivers/firmware/scmi/smt.c | 139 ++++++++++++++++++++++++++
> drivers/firmware/scmi/smt.h | 86 ++++++++++++++++
> 5 files changed, 333 insertions(+), 2 deletions(-)
> create mode 100644 drivers/firmware/scmi/mailbox_agent.c
> create mode 100644 drivers/firmware/scmi/smt.c
> create mode 100644 drivers/firmware/scmi/smt.h
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4 2/8] firmware: scmi: mailbox/smt agent device
2020-09-09 16:44 ` [PATCH v4 2/8] firmware: scmi: mailbox/smt agent device Etienne Carriere
2020-09-10 13:38 ` Simon Glass
@ 2020-10-01 14:07 ` Tom Rini
1 sibling, 0 replies; 23+ messages in thread
From: Tom Rini @ 2020-10-01 14:07 UTC (permalink / raw)
To: u-boot
On Wed, Sep 09, 2020 at 06:44:01PM +0200, Etienne Carriere wrote:
> This change implements a mailbox transport using SMT format for SCMI
> exchanges. This implementation follows the Linux kernel and
> SCP-firmware [1] as references implementation for SCMI message
> processing using SMT format for communication channel meta-data.
>
> Use of mailboxes in SCMI FDT bindings are defined in the Linux kernel
> DT bindings since v4.17.
>
> Links: [1] https://github.com/ARM-software/SCP-firmware
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
Applied to u-boot/next, thanks!
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20201001/f64a3af6/attachment.sig>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4 3/8] firmware: scmi: support Arm SMCCC transport
2020-09-09 16:44 [PATCH v4 1/8] firmware: add SCMI agent uclass Etienne Carriere
2020-09-09 16:44 ` [PATCH v4 2/8] firmware: scmi: mailbox/smt agent device Etienne Carriere
@ 2020-09-09 16:44 ` Etienne Carriere
2020-09-10 13:38 ` Simon Glass
2020-10-01 14:07 ` Tom Rini
2020-09-09 16:44 ` [PATCH v4 4/8] dt-bindings: arm: SCMI bindings documentation Etienne Carriere
` (5 subsequent siblings)
7 siblings, 2 replies; 23+ messages in thread
From: Etienne Carriere @ 2020-09-09 16:44 UTC (permalink / raw)
To: u-boot
This change implements a SMCCC transport for SCMI exchanges. This
implementation follows the Linux kernel as references implementation
for SCMI message processing, using the SMT format for communication
channel meta-data.
Use of SMCCC transport in SCMI FDT bindings are defined in the Linux
kernel DT bindings since v5.8. SMCCC with SMT is implemented in OP-TEE
from tag 3.9.0 [2].
Links: [2] https://github.com/OP-TEE/optee_os/commit/a58c4d706d23
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Cc: Simon Glass <sjg@chromium.org>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
---
Changes in v4:
- Update CONFIG_SCMI_FIRMWARE dependencies regarding CONFIG_ARM_SMCCC.
- Remove useless cast hence remove helper dev2agent() to get dev private.
- Fix header file inclusion ordering.
Changes in v3:
- This is a followup of the SCMI agent patches posted in
https://patchwork.ozlabs.org/project/uboot/list/?series=196253
The v3 splits commits and introduces a new uclass as requested.
- This patch implements the same Arm SMCCC SCMI agent as presented
in v2 but in its own source file smccc_agent.c, and based in smt.h.
---
drivers/firmware/scmi/Kconfig | 6 +-
drivers/firmware/scmi/Makefile | 1 +
drivers/firmware/scmi/smccc_agent.c | 89 +++++++++++++++++++++++++++++
3 files changed, 93 insertions(+), 3 deletions(-)
create mode 100644 drivers/firmware/scmi/smccc_agent.c
diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig
index c501bf4943..c3a109beac 100644
--- a/drivers/firmware/scmi/Kconfig
+++ b/drivers/firmware/scmi/Kconfig
@@ -2,7 +2,7 @@ config SCMI_FIRMWARE
bool "Enable SCMI support"
select FIRMWARE
select OF_TRANSLATE
- depends on SANDBOX || DM_MAILBOX
+ depends on SANDBOX || DM_MAILBOX || ARM_SMCCC
help
System Control and Management Interface (SCMI) is a communication
protocol that defines standard interfaces for power, performance
@@ -15,5 +15,5 @@ config SCMI_FIRMWARE
Communications between agent (client) and the SCMI server are
based on message exchange. Messages can be exchange over tranport
- channels as a mailbox device with some piece of identified shared
- memory.
+ channels as a mailbox device or an Arm SMCCC service with some
+ piece of identified shared memory.
diff --git a/drivers/firmware/scmi/Makefile b/drivers/firmware/scmi/Makefile
index d22f53efe7..2f782bbd55 100644
--- a/drivers/firmware/scmi/Makefile
+++ b/drivers/firmware/scmi/Makefile
@@ -1,4 +1,5 @@
obj-y += scmi_agent-uclass.o
obj-y += smt.o
+obj-$(CONFIG_ARM_SMCCC) += smccc_agent.o
obj-$(CONFIG_DM_MAILBOX) += mailbox_agent.o
obj-$(CONFIG_SANDBOX) += sandbox-scmi_agent.o
diff --git a/drivers/firmware/scmi/smccc_agent.c b/drivers/firmware/scmi/smccc_agent.c
new file mode 100644
index 0000000000..85dbf9195e
--- /dev/null
+++ b/drivers/firmware/scmi/smccc_agent.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Linaro Limited.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <scmi_agent.h>
+#include <scmi_agent-uclass.h>
+#include <dm/devres.h>
+#include <dm/device-internal.h>
+#include <linux/arm-smccc.h>
+#include <linux/compat.h>
+
+#include "smt.h"
+
+#define SMCCC_RET_NOT_SUPPORTED ((unsigned long)-1)
+
+/**
+ * struct scmi_smccc_channel - Description of an SCMI SMCCC transport
+ * @func_id: SMCCC function ID used by the SCMI transport
+ * @smt: Shared memory buffer
+ */
+struct scmi_smccc_channel {
+ ulong func_id;
+ struct scmi_smt smt;
+};
+
+static int scmi_smccc_process_msg(struct udevice *dev, struct scmi_msg *msg)
+{
+ struct scmi_smccc_channel *chan = dev_get_priv(dev);
+ struct arm_smccc_res res;
+ int ret;
+
+ ret = scmi_write_msg_to_smt(dev, &chan->smt, msg);
+ if (ret)
+ return ret;
+
+ arm_smccc_smc(chan->func_id, 0, 0, 0, 0, 0, 0, 0, &res);
+ if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
+ ret = -ENXIO;
+ else
+ ret = scmi_read_resp_from_smt(dev, &chan->smt, msg);
+
+ scmi_clear_smt_channel(&chan->smt);
+
+ return ret;
+}
+
+static int scmi_smccc_probe(struct udevice *dev)
+{
+ struct scmi_smccc_channel *chan = dev_get_priv(dev);
+ u32 func_id;
+ int ret;
+
+ if (dev_read_u32(dev, "arm,smc-id", &func_id)) {
+ dev_err(dev, "Missing property func-id\n");
+ return -EINVAL;
+ }
+
+ chan->func_id = func_id;
+
+ ret = scmi_dt_get_smt_buffer(dev, &chan->smt);
+ if (ret) {
+ dev_err(dev, "Failed to get smt resources: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id scmi_smccc_ids[] = {
+ { .compatible = "arm,scmi-smc" },
+ { }
+};
+
+static const struct scmi_agent_ops scmi_smccc_ops = {
+ .process_msg = scmi_smccc_process_msg,
+};
+
+U_BOOT_DRIVER(scmi_smccc) = {
+ .name = "scmi-over-smccc",
+ .id = UCLASS_SCMI_AGENT,
+ .of_match = scmi_smccc_ids,
+ .priv_auto_alloc_size = sizeof(struct scmi_smccc_channel),
+ .probe = scmi_smccc_probe,
+ .ops = &scmi_smccc_ops,
+};
--
2.17.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v4 3/8] firmware: scmi: support Arm SMCCC transport
2020-09-09 16:44 ` [PATCH v4 3/8] firmware: scmi: support Arm SMCCC transport Etienne Carriere
@ 2020-09-10 13:38 ` Simon Glass
2020-10-01 14:07 ` Tom Rini
1 sibling, 0 replies; 23+ messages in thread
From: Simon Glass @ 2020-09-10 13:38 UTC (permalink / raw)
To: u-boot
On Wed, 9 Sep 2020 at 10:44, Etienne Carriere
<etienne.carriere@linaro.org> wrote:
>
> This change implements a SMCCC transport for SCMI exchanges. This
> implementation follows the Linux kernel as references implementation
> for SCMI message processing, using the SMT format for communication
> channel meta-data.
>
> Use of SMCCC transport in SCMI FDT bindings are defined in the Linux
> kernel DT bindings since v5.8. SMCCC with SMT is implemented in OP-TEE
> from tag 3.9.0 [2].
>
> Links: [2] https://github.com/OP-TEE/optee_os/commit/a58c4d706d23
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> ---
>
> Changes in v4:
> - Update CONFIG_SCMI_FIRMWARE dependencies regarding CONFIG_ARM_SMCCC.
> - Remove useless cast hence remove helper dev2agent() to get dev private.
> - Fix header file inclusion ordering.
>
> Changes in v3:
> - This is a followup of the SCMI agent patches posted in
> https://patchwork.ozlabs.org/project/uboot/list/?series=196253
> The v3 splits commits and introduces a new uclass as requested.
> - This patch implements the same Arm SMCCC SCMI agent as presented
> in v2 but in its own source file smccc_agent.c, and based in smt.h.
> ---
> drivers/firmware/scmi/Kconfig | 6 +-
> drivers/firmware/scmi/Makefile | 1 +
> drivers/firmware/scmi/smccc_agent.c | 89 +++++++++++++++++++++++++++++
> 3 files changed, 93 insertions(+), 3 deletions(-)
> create mode 100644 drivers/firmware/scmi/smccc_agent.c
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4 3/8] firmware: scmi: support Arm SMCCC transport
2020-09-09 16:44 ` [PATCH v4 3/8] firmware: scmi: support Arm SMCCC transport Etienne Carriere
2020-09-10 13:38 ` Simon Glass
@ 2020-10-01 14:07 ` Tom Rini
1 sibling, 0 replies; 23+ messages in thread
From: Tom Rini @ 2020-10-01 14:07 UTC (permalink / raw)
To: u-boot
On Wed, Sep 09, 2020 at 06:44:02PM +0200, Etienne Carriere wrote:
> This change implements a SMCCC transport for SCMI exchanges. This
> implementation follows the Linux kernel as references implementation
> for SCMI message processing, using the SMT format for communication
> channel meta-data.
>
> Use of SMCCC transport in SCMI FDT bindings are defined in the Linux
> kernel DT bindings since v5.8. SMCCC with SMT is implemented in OP-TEE
> from tag 3.9.0 [2].
>
> Links: [2] https://github.com/OP-TEE/optee_os/commit/a58c4d706d23
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
Applied to u-boot/next, thanks!
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20201001/06594b70/attachment.sig>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4 4/8] dt-bindings: arm: SCMI bindings documentation
2020-09-09 16:44 [PATCH v4 1/8] firmware: add SCMI agent uclass Etienne Carriere
2020-09-09 16:44 ` [PATCH v4 2/8] firmware: scmi: mailbox/smt agent device Etienne Carriere
2020-09-09 16:44 ` [PATCH v4 3/8] firmware: scmi: support Arm SMCCC transport Etienne Carriere
@ 2020-09-09 16:44 ` Etienne Carriere
2020-09-10 13:38 ` Simon Glass
2020-10-01 14:07 ` Tom Rini
2020-09-09 16:44 ` [PATCH v4 5/8] clk: add clock driver for SCMI agents Etienne Carriere
` (4 subsequent siblings)
7 siblings, 2 replies; 23+ messages in thread
From: Etienne Carriere @ 2020-09-09 16:44 UTC (permalink / raw)
To: u-boot
Dump SCMI DT bindings documentation from Linux kernel source
tree v5.8-rc1.
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
No change in v4.
No change in v3.
Changes in v2:
- No change but added R-b tag.
- Yet a question: do we need to add this binding doc in U-Boot
since already existing in Linux DT bindings docs? Related to review
comment https://www.mail-archive.com/u-boot at lists.denx.de/msg377725.html
---
doc/device-tree-bindings/arm/arm,scmi.txt | 197 ++++++++++++++++++++++
1 file changed, 197 insertions(+)
create mode 100644 doc/device-tree-bindings/arm/arm,scmi.txt
diff --git a/doc/device-tree-bindings/arm/arm,scmi.txt b/doc/device-tree-bindings/arm/arm,scmi.txt
new file mode 100644
index 0000000000..1f293ea24c
--- /dev/null
+++ b/doc/device-tree-bindings/arm/arm,scmi.txt
@@ -0,0 +1,197 @@
+System Control and Management Interface (SCMI) Message Protocol
+----------------------------------------------------------
+
+The SCMI is intended to allow agents such as OSPM to manage various functions
+that are provided by the hardware platform it is running on, including power
+and performance functions.
+
+This binding is intended to define the interface the firmware implementing
+the SCMI as described in ARM document number ARM DEN 0056A ("ARM System Control
+and Management Interface Platform Design Document")[0] provide for OSPM in
+the device tree.
+
+Required properties:
+
+The scmi node with the following properties shall be under the /firmware/ node.
+
+- compatible : shall be "arm,scmi" or "arm,scmi-smc" for smc/hvc transports
+- mboxes: List of phandle and mailbox channel specifiers. It should contain
+ exactly one or two mailboxes, one for transmitting messages("tx")
+ and another optional for receiving the notifications("rx") if
+ supported.
+- shmem : List of phandle pointing to the shared memory(SHM) area as per
+ generic mailbox client binding.
+- #address-cells : should be '1' if the device has sub-nodes, maps to
+ protocol identifier for a given sub-node.
+- #size-cells : should be '0' as 'reg' property doesn't have any size
+ associated with it.
+- arm,smc-id : SMC id required when using smc or hvc transports
+
+Optional properties:
+
+- mbox-names: shall be "tx" or "rx" depending on mboxes entries.
+
+See Documentation/devicetree/bindings/mailbox/mailbox.txt for more details
+about the generic mailbox controller and client driver bindings.
+
+The mailbox is the only permitted method of calling the SCMI firmware.
+Mailbox doorbell is used as a mechanism to alert the presence of a
+messages and/or notification.
+
+Each protocol supported shall have a sub-node with corresponding compatible
+as described in the following sections. If the platform supports dedicated
+communication channel for a particular protocol, the 3 properties namely:
+mboxes, mbox-names and shmem shall be present in the sub-node corresponding
+to that protocol.
+
+Clock/Performance bindings for the clocks/OPPs based on SCMI Message Protocol
+------------------------------------------------------------
+
+This binding uses the common clock binding[1].
+
+Required properties:
+- #clock-cells : Should be 1. Contains the Clock ID value used by SCMI commands.
+
+Power domain bindings for the power domains based on SCMI Message Protocol
+------------------------------------------------------------
+
+This binding for the SCMI power domain providers uses the generic power
+domain binding[2].
+
+Required properties:
+ - #power-domain-cells : Should be 1. Contains the device or the power
+ domain ID value used by SCMI commands.
+
+Sensor bindings for the sensors based on SCMI Message Protocol
+--------------------------------------------------------------
+SCMI provides an API to access the various sensors on the SoC.
+
+Required properties:
+- #thermal-sensor-cells: should be set to 1. This property follows the
+ thermal device tree bindings[3].
+
+ Valid cell values are raw identifiers (Sensor ID)
+ as used by the firmware. Refer to platform details
+ for your implementation for the IDs to use.
+
+Reset signal bindings for the reset domains based on SCMI Message Protocol
+------------------------------------------------------------
+
+This binding for the SCMI reset domain providers uses the generic reset
+signal binding[5].
+
+Required properties:
+ - #reset-cells : Should be 1. Contains the reset domain ID value used
+ by SCMI commands.
+
+SRAM and Shared Memory for SCMI
+-------------------------------
+
+A small area of SRAM is reserved for SCMI communication between application
+processors and SCP.
+
+The properties should follow the generic mmio-sram description found in [4]
+
+Each sub-node represents the reserved area for SCMI.
+
+Required sub-node properties:
+- reg : The base offset and size of the reserved area with the SRAM
+- compatible : should be "arm,scmi-shmem" for Non-secure SRAM based
+ shared memory
+
+[0] http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/index.html
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Documentation/devicetree/bindings/power/power-domain.yaml
+[3] Documentation/devicetree/bindings/thermal/thermal.txt
+[4] Documentation/devicetree/bindings/sram/sram.yaml
+[5] Documentation/devicetree/bindings/reset/reset.txt
+
+Example:
+
+sram at 50000000 {
+ compatible = "mmio-sram";
+ reg = <0x0 0x50000000 0x0 0x10000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x0 0x50000000 0x10000>;
+
+ cpu_scp_lpri: scp-shmem at 0 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x0 0x200>;
+ };
+
+ cpu_scp_hpri: scp-shmem at 200 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x200 0x200>;
+ };
+};
+
+mailbox at 40000000 {
+ ....
+ #mbox-cells = <1>;
+ reg = <0x0 0x40000000 0x0 0x10000>;
+};
+
+firmware {
+
+ ...
+
+ scmi {
+ compatible = "arm,scmi";
+ mboxes = <&mailbox 0 &mailbox 1>;
+ mbox-names = "tx", "rx";
+ shmem = <&cpu_scp_lpri &cpu_scp_hpri>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ scmi_devpd: protocol at 11 {
+ reg = <0x11>;
+ #power-domain-cells = <1>;
+ };
+
+ scmi_dvfs: protocol at 13 {
+ reg = <0x13>;
+ #clock-cells = <1>;
+ };
+
+ scmi_clk: protocol at 14 {
+ reg = <0x14>;
+ #clock-cells = <1>;
+ };
+
+ scmi_sensors0: protocol at 15 {
+ reg = <0x15>;
+ #thermal-sensor-cells = <1>;
+ };
+
+ scmi_reset: protocol at 16 {
+ reg = <0x16>;
+ #reset-cells = <1>;
+ };
+ };
+};
+
+cpu at 0 {
+ ...
+ reg = <0 0>;
+ clocks = <&scmi_dvfs 0>;
+};
+
+hdlcd at 7ff60000 {
+ ...
+ reg = <0 0x7ff60000 0 0x1000>;
+ clocks = <&scmi_clk 4>;
+ power-domains = <&scmi_devpd 1>;
+ resets = <&scmi_reset 10>;
+};
+
+thermal-zones {
+ soc_thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <1000>;
+ /* sensor ID */
+ thermal-sensors = <&scmi_sensors0 3>;
+ ...
+ };
+};
--
2.17.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v4 4/8] dt-bindings: arm: SCMI bindings documentation
2020-09-09 16:44 ` [PATCH v4 4/8] dt-bindings: arm: SCMI bindings documentation Etienne Carriere
@ 2020-09-10 13:38 ` Simon Glass
2020-10-01 14:07 ` Tom Rini
1 sibling, 0 replies; 23+ messages in thread
From: Simon Glass @ 2020-09-10 13:38 UTC (permalink / raw)
To: u-boot
On Wed, 9 Sep 2020 at 10:44, Etienne Carriere
<etienne.carriere@linaro.org> wrote:
>
> Dump SCMI DT bindings documentation from Linux kernel source
> tree v5.8-rc1.
>
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> ---
>
> No change in v4.
>
> No change in v3.
>
> Changes in v2:
> - No change but added R-b tag.
> - Yet a question: do we need to add this binding doc in U-Boot
> since already existing in Linux DT bindings docs? Related to review
> comment https://www.mail-archive.com/u-boot at lists.denx.de/msg377725.html
Yes please
> ---
> doc/device-tree-bindings/arm/arm,scmi.txt | 197 ++++++++++++++++++++++
> 1 file changed, 197 insertions(+)
> create mode 100644 doc/device-tree-bindings/arm/arm,scmi.txt
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4 4/8] dt-bindings: arm: SCMI bindings documentation
2020-09-09 16:44 ` [PATCH v4 4/8] dt-bindings: arm: SCMI bindings documentation Etienne Carriere
2020-09-10 13:38 ` Simon Glass
@ 2020-10-01 14:07 ` Tom Rini
1 sibling, 0 replies; 23+ messages in thread
From: Tom Rini @ 2020-10-01 14:07 UTC (permalink / raw)
To: u-boot
On Wed, Sep 09, 2020 at 06:44:03PM +0200, Etienne Carriere wrote:
> Dump SCMI DT bindings documentation from Linux kernel source
> tree v5.8-rc1.
>
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Simon Glass <sjg@chromium.org>
Applied to u-boot/next, thanks!
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20201001/8c9bcf67/attachment.sig>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4 5/8] clk: add clock driver for SCMI agents
2020-09-09 16:44 [PATCH v4 1/8] firmware: add SCMI agent uclass Etienne Carriere
` (2 preceding siblings ...)
2020-09-09 16:44 ` [PATCH v4 4/8] dt-bindings: arm: SCMI bindings documentation Etienne Carriere
@ 2020-09-09 16:44 ` Etienne Carriere
2020-09-10 13:38 ` Simon Glass
2020-10-01 14:07 ` Tom Rini
2020-09-09 16:44 ` [PATCH v4 6/8] firmware: scmi: sandbox test for SCMI clocks Etienne Carriere
` (3 subsequent siblings)
7 siblings, 2 replies; 23+ messages in thread
From: Etienne Carriere @ 2020-09-09 16:44 UTC (permalink / raw)
To: u-boot
This change introduces a clock driver for SCMI agent devices. When
SCMI agent and SCMI clock drivers are enabled, SCMI agent binds a
clock device for each SCMI clock protocol devices enabled in the FDT.
SCMI clock driver is embedded upon CONFIG_CLK_SCMI=y. If enabled,
CONFIG_SCMI_AGENT is also enabled.
SCMI Clock protocol is defined in the SCMI specification [1].
Links: [1] https://developer.arm.com/architectures/system-architectures/software-standards/scmi
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Cc: Lukasz Majewski <lukma@denx.de>
Cc: Simon Glass <sjg@chromium.org>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
---
Changes in v4:
- Condition DM_GET_DRIVER(scmi_clock) to IS_ENABLED(CONFIG_CLK_SCMI)
to prevent a build error (linker) when CONFIG_CLK_SCMI is disabled.
Changes in v3:
- Rebased in the series without major conflict.
Changes in v2:
- CONFIG_CLK_SCMI depends on CONFIG_SCMI_FIRMWARE instead of
selecting CONFIG_SCMI_FIRMWARE.
- Add inline comment description for structures and moves them to
source file top. Add/fixup some functions inline description comments.
- Replace rc with ret as return value local variable label.
- Fix scmi_clk_get_rate() return value to propagate error number.
- Fix scmi_clk_set_rate() to request synchronous rate set operation:
drop flag SCMI_CLK_RATE_ASYNC_NORESP in the SCMI message payload.
- Fix scmi_clk_set_rate() return value to return clock effective rate
on success.
---
drivers/clk/Kconfig | 8 ++
drivers/clk/Makefile | 1 +
drivers/clk/clk_scmi.c | 99 +++++++++++++++++++++++
drivers/firmware/scmi/scmi_agent-uclass.c | 14 +++-
include/scmi_protocols.h | 78 ++++++++++++++++++
5 files changed, 197 insertions(+), 3 deletions(-)
create mode 100644 drivers/clk/clk_scmi.c
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 6003e140b5..4dfbad7986 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -159,6 +159,14 @@ config CLK_CDCE9XX
Enable the clock synthesizer driver for CDCE913/925/937/949
series of chips.
+config CLK_SCMI
+ bool "Enable SCMI clock driver"
+ depends on SCMI_FIRMWARE
+ help
+ Enable this option if you want to support clock devices exposed
+ by a SCMI agent based on SCMI clock protocol communication
+ with a SCMI server.
+
source "drivers/clk/analogbits/Kconfig"
source "drivers/clk/at91/Kconfig"
source "drivers/clk/exynos/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index cda4b4b605..d1e295ac7c 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o
obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o
obj-$(CONFIG_CLK_OWL) += owl/
obj-$(CONFIG_CLK_RENESAS) += renesas/
+obj-$(CONFIG_CLK_SCMI) += clk_scmi.o
obj-$(CONFIG_CLK_SIFIVE) += sifive/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o
diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
new file mode 100644
index 0000000000..93a4819501
--- /dev/null
+++ b/drivers/clk/clk_scmi.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019-2020 Linaro Limited
+ */
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <scmi_agent.h>
+#include <scmi_protocols.h>
+#include <asm/types.h>
+
+static int scmi_clk_gate(struct clk *clk, int enable)
+{
+ struct scmi_clk_state_in in = {
+ .clock_id = clk->id,
+ .attributes = enable,
+ };
+ struct scmi_clk_state_out out;
+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_CONFIG_SET,
+ in, out);
+ int ret;
+
+ ret = devm_scmi_process_msg(clk->dev->parent, &msg);
+ if (ret)
+ return ret;
+
+ return scmi_to_linux_errno(out.status);
+}
+
+static int scmi_clk_enable(struct clk *clk)
+{
+ return scmi_clk_gate(clk, 1);
+}
+
+static int scmi_clk_disable(struct clk *clk)
+{
+ return scmi_clk_gate(clk, 0);
+}
+
+static ulong scmi_clk_get_rate(struct clk *clk)
+{
+ struct scmi_clk_rate_get_in in = {
+ .clock_id = clk->id,
+ };
+ struct scmi_clk_rate_get_out out;
+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_RATE_GET,
+ in, out);
+ int ret;
+
+ ret = devm_scmi_process_msg(clk->dev->parent, &msg);
+ if (ret < 0)
+ return ret;
+
+ ret = scmi_to_linux_errno(out.status);
+ if (ret < 0)
+ return ret;
+
+ return (ulong)(((u64)out.rate_msb << 32) | out.rate_lsb);
+}
+
+static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct scmi_clk_rate_set_in in = {
+ .clock_id = clk->id,
+ .flags = SCMI_CLK_RATE_ROUND_CLOSEST,
+ .rate_lsb = (u32)rate,
+ .rate_msb = (u32)((u64)rate >> 32),
+ };
+ struct scmi_clk_rate_set_out out;
+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_RATE_SET,
+ in, out);
+ int ret;
+
+ ret = devm_scmi_process_msg(clk->dev->parent, &msg);
+ if (ret < 0)
+ return ret;
+
+ ret = scmi_to_linux_errno(out.status);
+ if (ret < 0)
+ return ret;
+
+ return scmi_clk_get_rate(clk);
+}
+
+static const struct clk_ops scmi_clk_ops = {
+ .enable = scmi_clk_enable,
+ .disable = scmi_clk_disable,
+ .get_rate = scmi_clk_get_rate,
+ .set_rate = scmi_clk_set_rate,
+};
+
+U_BOOT_DRIVER(scmi_clock) = {
+ .name = "scmi_clk",
+ .id = UCLASS_CLK,
+ .ops = &scmi_clk_ops,
+};
diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c
index 67a6f907c9..1f36f23b6d 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -58,9 +58,9 @@ static int scmi_bind_protocols(struct udevice *dev)
{
int ret = 0;
ofnode node;
- struct driver *drv;
dev_for_each_subnode(node, dev) {
+ struct driver *drv = NULL;
u32 protocol_id;
if (!ofnode_is_available(node))
@@ -70,9 +70,17 @@ static int scmi_bind_protocols(struct udevice *dev)
continue;
switch (protocol_id) {
+ case SCMI_PROTOCOL_ID_CLOCK:
+ if (IS_ENABLED(CONFIG_CLK_SCMI))
+ drv = DM_GET_DRIVER(scmi_clock);
+ break;
default:
- dev_info(dev, "Ignore unsupported SCMI protocol %#x\n",
- protocol_id);
+ break;
+ }
+
+ if (!drv) {
+ dev_dbg(dev, "Ignore unsupported SCMI protocol %#x\n",
+ protocol_id);
continue;
}
diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
index 86a2d109c8..4778bcfc47 100644
--- a/include/scmi_protocols.h
+++ b/include/scmi_protocols.h
@@ -7,6 +7,7 @@
#define _SCMI_PROTOCOLS_H
#include <linux/bitops.h>
+#include <asm/types.h>
/*
* Subset the SCMI protocols definition
@@ -38,4 +39,81 @@ enum scmi_status_code {
SCMI_PROTOCOL_ERROR = -10,
};
+/*
+ * SCMI Clock Protocol
+ */
+
+enum scmi_clock_message_id {
+ SCMI_CLOCK_RATE_SET = 0x5,
+ SCMI_CLOCK_RATE_GET = 0x6,
+ SCMI_CLOCK_CONFIG_SET = 0x7,
+};
+
+#define SCMI_CLK_RATE_ASYNC_NOTIFY BIT(0)
+#define SCMI_CLK_RATE_ASYNC_NORESP (BIT(0) | BIT(1))
+#define SCMI_CLK_RATE_ROUND_DOWN 0
+#define SCMI_CLK_RATE_ROUND_UP BIT(2)
+#define SCMI_CLK_RATE_ROUND_CLOSEST BIT(3)
+
+/**
+ * struct scmi_clk_state_in - Message payload for CLOCK_CONFIG_SET command
+ * @clock_id: SCMI clock ID
+ * @attributes: Attributes of the targets clock state
+ */
+struct scmi_clk_state_in {
+ u32 clock_id;
+ u32 attributes;
+};
+
+/**
+ * struct scmi_clk_state_out - Response payload for CLOCK_CONFIG_SET command
+ * @status: SCMI command status
+ */
+struct scmi_clk_state_out {
+ s32 status;
+};
+
+/**
+ * struct scmi_clk_state_in - Message payload for CLOCK_RATE_GET command
+ * @clock_id: SCMI clock ID
+ * @attributes: Attributes of the targets clock state
+ */
+struct scmi_clk_rate_get_in {
+ u32 clock_id;
+};
+
+/**
+ * struct scmi_clk_rate_get_out - Response payload for CLOCK_RATE_GET command
+ * @status: SCMI command status
+ * @rate_lsb: 32bit LSB of the clock rate in Hertz
+ * @rate_msb: 32bit MSB of the clock rate in Hertz
+ */
+struct scmi_clk_rate_get_out {
+ s32 status;
+ u32 rate_lsb;
+ u32 rate_msb;
+};
+
+/**
+ * struct scmi_clk_state_in - Message payload for CLOCK_RATE_SET command
+ * @clock_id: SCMI clock ID
+ * @flags: Flags for the clock rate set request
+ * @rate_lsb: 32bit LSB of the clock rate in Hertz
+ * @rate_msb: 32bit MSB of the clock rate in Hertz
+ */
+struct scmi_clk_rate_set_in {
+ u32 clock_id;
+ u32 flags;
+ u32 rate_lsb;
+ u32 rate_msb;
+};
+
+/**
+ * struct scmi_clk_rate_set_out - Response payload for CLOCK_RATE_SET command
+ * @status: SCMI command status
+ */
+struct scmi_clk_rate_set_out {
+ s32 status;
+};
+
#endif /* _SCMI_PROTOCOLS_H */
--
2.17.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v4 5/8] clk: add clock driver for SCMI agents
2020-09-09 16:44 ` [PATCH v4 5/8] clk: add clock driver for SCMI agents Etienne Carriere
@ 2020-09-10 13:38 ` Simon Glass
2020-10-01 14:07 ` Tom Rini
1 sibling, 0 replies; 23+ messages in thread
From: Simon Glass @ 2020-09-10 13:38 UTC (permalink / raw)
To: u-boot
On Wed, 9 Sep 2020 at 10:44, Etienne Carriere
<etienne.carriere@linaro.org> wrote:
>
> This change introduces a clock driver for SCMI agent devices. When
> SCMI agent and SCMI clock drivers are enabled, SCMI agent binds a
> clock device for each SCMI clock protocol devices enabled in the FDT.
>
> SCMI clock driver is embedded upon CONFIG_CLK_SCMI=y. If enabled,
> CONFIG_SCMI_AGENT is also enabled.
>
> SCMI Clock protocol is defined in the SCMI specification [1].
>
> Links: [1] https://developer.arm.com/architectures/system-architectures/software-standards/scmi
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Cc: Lukasz Majewski <lukma@denx.de>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> ---
>
> Changes in v4:
> - Condition DM_GET_DRIVER(scmi_clock) to IS_ENABLED(CONFIG_CLK_SCMI)
> to prevent a build error (linker) when CONFIG_CLK_SCMI is disabled.
>
> Changes in v3:
> - Rebased in the series without major conflict.
>
> Changes in v2:
> - CONFIG_CLK_SCMI depends on CONFIG_SCMI_FIRMWARE instead of
> selecting CONFIG_SCMI_FIRMWARE.
> - Add inline comment description for structures and moves them to
> source file top. Add/fixup some functions inline description comments.
> - Replace rc with ret as return value local variable label.
> - Fix scmi_clk_get_rate() return value to propagate error number.
> - Fix scmi_clk_set_rate() to request synchronous rate set operation:
> drop flag SCMI_CLK_RATE_ASYNC_NORESP in the SCMI message payload.
> - Fix scmi_clk_set_rate() return value to return clock effective rate
> on success.
> ---
> drivers/clk/Kconfig | 8 ++
> drivers/clk/Makefile | 1 +
> drivers/clk/clk_scmi.c | 99 +++++++++++++++++++++++
> drivers/firmware/scmi/scmi_agent-uclass.c | 14 +++-
> include/scmi_protocols.h | 78 ++++++++++++++++++
> 5 files changed, 197 insertions(+), 3 deletions(-)
> create mode 100644 drivers/clk/clk_scmi.c
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4 5/8] clk: add clock driver for SCMI agents
2020-09-09 16:44 ` [PATCH v4 5/8] clk: add clock driver for SCMI agents Etienne Carriere
2020-09-10 13:38 ` Simon Glass
@ 2020-10-01 14:07 ` Tom Rini
1 sibling, 0 replies; 23+ messages in thread
From: Tom Rini @ 2020-10-01 14:07 UTC (permalink / raw)
To: u-boot
On Wed, Sep 09, 2020 at 06:44:04PM +0200, Etienne Carriere wrote:
> This change introduces a clock driver for SCMI agent devices. When
> SCMI agent and SCMI clock drivers are enabled, SCMI agent binds a
> clock device for each SCMI clock protocol devices enabled in the FDT.
>
> SCMI clock driver is embedded upon CONFIG_CLK_SCMI=y. If enabled,
> CONFIG_SCMI_AGENT is also enabled.
>
> SCMI Clock protocol is defined in the SCMI specification [1].
>
> Links: [1] https://developer.arm.com/architectures/system-architectures/software-standards/scmi
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Cc: Lukasz Majewski <lukma@denx.de>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
Applied to u-boot/next, thanks!
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20201001/1431e3fd/attachment.sig>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4 6/8] firmware: scmi: sandbox test for SCMI clocks
2020-09-09 16:44 [PATCH v4 1/8] firmware: add SCMI agent uclass Etienne Carriere
` (3 preceding siblings ...)
2020-09-09 16:44 ` [PATCH v4 5/8] clk: add clock driver for SCMI agents Etienne Carriere
@ 2020-09-09 16:44 ` Etienne Carriere
2020-09-10 13:38 ` Simon Glass
2020-10-01 14:07 ` Tom Rini
2020-09-09 16:44 ` [PATCH v4 7/8] reset: add reset controller driver for SCMI agents Etienne Carriere
` (2 subsequent siblings)
7 siblings, 2 replies; 23+ messages in thread
From: Etienne Carriere @ 2020-09-09 16:44 UTC (permalink / raw)
To: u-boot
Add tests for SCMI clocks. A test device driver sandbox-scmi_devices.c
is used to get clock resources, allowing further clock manipulation.
Change sandbox-smci_agent to emulate 3 clocks exposed through 2 agents.
Add DM test scmi_clocks to test these 3 clocks.
Update DM test sandbox_scmi_agent with load/remove test sequences
factorized by {load|remove}_sandbox_scmi_test_devices() helper functions.
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Cc: Simon Glass <sjg@chromium.org>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
---
Changes in v4:
- Move SCMI test devices instances from BSS to test device private data
and update test/dm/scmi.c accordingly.
- Update sandbox_scmi_devices_ctx() helper to add device reference arg.
- Fix spelling issues in inline comments.
- Rename local variables rc to ret for consistency.
Changes in v3:
- New commit in the series, addresses review comments on test support.
ut_dm_scmi_clocks test SCMI are found and behave as expected for the
implemented clk uclass methods.
---
arch/sandbox/dts/test.dts | 15 ++
arch/sandbox/include/asm/scmi_test.h | 39 +++++
configs/sandbox_defconfig | 1 +
drivers/firmware/scmi/Makefile | 2 +-
drivers/firmware/scmi/sandbox-scmi_agent.c | 169 ++++++++++++++++++-
drivers/firmware/scmi/sandbox-scmi_devices.c | 75 ++++++++
test/dm/scmi.c | 141 +++++++++++++++-
7 files changed, 431 insertions(+), 11 deletions(-)
create mode 100644 drivers/firmware/scmi/sandbox-scmi_devices.c
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index dd3b43885e..61acd8d79f 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -361,6 +361,11 @@
compatible = "sandbox,scmi-agent";
#address-cells = <1>;
#size-cells = <0>;
+
+ clk_scmi0: protocol at 14 {
+ reg = <0x14>;
+ #clock-cells = <1>;
+ };
};
sandbox-scmi-agent at 1 {
@@ -368,6 +373,11 @@
#address-cells = <1>;
#size-cells = <0>;
+ clk_scmi1: protocol at 14 {
+ reg = <0x14>;
+ #clock-cells = <1>;
+ };
+
protocol at 10 {
reg = <0x10>;
};
@@ -1052,6 +1062,11 @@
compatible = "sandbox,virtio2";
};
+ sandbox_scmi {
+ compatible = "sandbox,scmi-devices";
+ clocks = <&clk_scmi0 7>, <&clk_scmi0 3>, <&clk_scmi1 1>;
+ };
+
pinctrl {
compatible = "sandbox,pinctrl";
diff --git a/arch/sandbox/include/asm/scmi_test.h b/arch/sandbox/include/asm/scmi_test.h
index a811fe19c3..63093fdb4d 100644
--- a/arch/sandbox/include/asm/scmi_test.h
+++ b/arch/sandbox/include/asm/scmi_test.h
@@ -10,12 +10,28 @@ struct udevice;
struct sandbox_scmi_agent;
struct sandbox_scmi_service;
+/**
+ * struct sandbox_scmi_clk - Simulated clock exposed by SCMI
+ * @id: Identifier of the clock used in the SCMI protocol
+ * @enabled: Clock state: true if enabled, false if disabled
+ * @rate: Clock rate in Hertz
+ */
+struct sandbox_scmi_clk {
+ uint id;
+ bool enabled;
+ ulong rate;
+};
+
/**
* struct sandbox_scmi_agent - Simulated SCMI service seen by SCMI agent
* @idx: Identifier for the SCMI agent, its index
+ * @clk: Simulated clocks
+ * @clk_count: Simulated clocks array size
*/
struct sandbox_scmi_agent {
uint idx;
+ struct sandbox_scmi_clk *clk;
+ size_t clk_count;
};
/**
@@ -28,16 +44,39 @@ struct sandbox_scmi_service {
size_t agent_count;
};
+/**
+ * struct sandbox_scmi_devices - Reference to devices probed through SCMI
+ * @clk: Array the clock devices
+ * @clk_count: Number of clock devices probed
+ */
+struct sandbox_scmi_devices {
+ struct clk *clk;
+ size_t clk_count;
+};
+
#ifdef CONFIG_SCMI_FIRMWARE
/**
* sandbox_scmi_service_context - Get the simulated SCMI services context
* @return: Reference to backend simulated resources state
*/
struct sandbox_scmi_service *sandbox_scmi_service_ctx(void);
+
+/**
+ * sandbox_scmi_devices_get_ref - Get references to devices accessed through SCMI
+ * @dev: Reference to the test device used get test resources
+ * @return: Reference to the devices probed by the SCMI test
+ */
+struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(struct udevice *dev);
#else
static inline struct sandbox_scmi_service *sandbox_scmi_service_ctx(void)
{
return NULL;
}
+
+static inline
+struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(struct udevice *dev)
+{
+ return NULL;
+}
#endif /* CONFIG_SCMI_FIRMWARE */
#endif /* __SANDBOX_SCMI_TEST_H */
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 2c130c01f0..7d71c805dc 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -122,6 +122,7 @@ CONFIG_BUTTON=y
CONFIG_BUTTON_GPIO=y
CONFIG_CLK=y
CONFIG_CLK_COMPOSITE_CCF=y
+CONFIG_CLK_SCMI=y
CONFIG_SANDBOX_CLK_CCF=y
CONFIG_CPU=y
CONFIG_DM_DEMO=y
diff --git a/drivers/firmware/scmi/Makefile b/drivers/firmware/scmi/Makefile
index 2f782bbd55..e1e0224066 100644
--- a/drivers/firmware/scmi/Makefile
+++ b/drivers/firmware/scmi/Makefile
@@ -2,4 +2,4 @@ obj-y += scmi_agent-uclass.o
obj-y += smt.o
obj-$(CONFIG_ARM_SMCCC) += smccc_agent.o
obj-$(CONFIG_DM_MAILBOX) += mailbox_agent.o
-obj-$(CONFIG_SANDBOX) += sandbox-scmi_agent.o
+obj-$(CONFIG_SANDBOX) += sandbox-scmi_agent.o sandbox-scmi_devices.o
diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c b/drivers/firmware/scmi/sandbox-scmi_agent.c
index 3179438aab..ff590988a6 100644
--- a/drivers/firmware/scmi/sandbox-scmi_agent.c
+++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
@@ -16,18 +16,34 @@
/*
* The sandbox SCMI agent driver simulates to some extend a SCMI message
* processing. It simulates few of the SCMI services for some of the
- * SCMI protocols embedded in U-Boot. Currently none.
+ * SCMI protocols embedded in U-Boot. Currently:
+ * - SCMI clock protocol: emulate 2 agents each exposing few clocks
*
- * This driver simulates 2 SCMI agents for test purpose.
+ * Agent #0 simulates 2 clocks.
+ * See IDs in scmi0_clk[] and "sandbox-scmi-agent at 0" in test.dts.
+ *
+ * Agent #1 simulates 1 clock.
+ * See IDs in scmi1_clk[] and "sandbox-scmi-agent at 1" in test.dts.
+ *
+ * All clocks are default disabled.
*
* This Driver exports sandbox_scmi_service_ct() for the test sequence to
* get the state of the simulated services (clock state, rate, ...) and
* check back-end device state reflects the request send through the
- * various uclass devices, currently nothing.
+ * various uclass devices, currently only clock controllers.
*/
#define SANDBOX_SCMI_AGENT_COUNT 2
+static struct sandbox_scmi_clk scmi0_clk[] = {
+ { .id = 7, .rate = 1000 },
+ { .id = 3, .rate = 333 },
+};
+
+static struct sandbox_scmi_clk scmi1_clk[] = {
+ { .id = 1, .rate = 44 },
+};
+
/* The list saves to simulted end devices references for test purpose */
struct sandbox_scmi_agent *sandbox_scmi_agent_list[SANDBOX_SCMI_AGENT_COUNT];
@@ -46,17 +62,158 @@ static void debug_print_agent_state(struct udevice *dev, char *str)
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
dev_dbg(dev, "Dump sandbox_scmi_agent %u: %s\n", agent->idx, str);
+ dev_dbg(dev, " scmi%u_clk (%zu): %d/%ld, %d/%ld, %d/%ld, ...\n",
+ agent->idx,
+ agent->clk_count,
+ agent->clk_count ? agent->clk[0].enabled : -1,
+ agent->clk_count ? agent->clk[0].rate : -1,
+ agent->clk_count > 1 ? agent->clk[1].enabled : -1,
+ agent->clk_count > 1 ? agent->clk[1].rate : -1,
+ agent->clk_count > 2 ? agent->clk[2].enabled : -1,
+ agent->clk_count > 2 ? agent->clk[2].rate : -1);
};
+static struct sandbox_scmi_clk *get_scmi_clk_state(uint agent_id, uint clock_id)
+{
+ struct sandbox_scmi_clk *target = NULL;
+ size_t target_count = 0;
+ size_t n;
+
+ switch (agent_id) {
+ case 0:
+ target = scmi0_clk;
+ target_count = ARRAY_SIZE(scmi0_clk);
+ break;
+ case 1:
+ target = scmi1_clk;
+ target_count = ARRAY_SIZE(scmi1_clk);
+ break;
+ default:
+ return NULL;
+ }
+
+ for (n = 0; n < target_count; n++)
+ if (target[n].id == clock_id)
+ return target + n;
+
+ return NULL;
+}
+
+/*
+ * Sandbox SCMI agent ops
+ */
+
+static int sandbox_scmi_clock_rate_set(struct udevice *dev,
+ struct scmi_msg *msg)
+{
+ struct sandbox_scmi_agent *agent = dev_get_priv(dev);
+ struct scmi_clk_rate_set_in *in = NULL;
+ struct scmi_clk_rate_set_out *out = NULL;
+ struct sandbox_scmi_clk *clk_state = NULL;
+
+ if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
+ !msg->out_msg || msg->out_msg_sz < sizeof(*out))
+ return -EINVAL;
+
+ in = (struct scmi_clk_rate_set_in *)msg->in_msg;
+ out = (struct scmi_clk_rate_set_out *)msg->out_msg;
+
+ clk_state = get_scmi_clk_state(agent->idx, in->clock_id);
+ if (!clk_state) {
+ dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);
+
+ out->status = SCMI_NOT_FOUND;
+ } else {
+ u64 rate = ((u64)in->rate_msb << 32) + in->rate_lsb;
+
+ clk_state->rate = (ulong)rate;
+
+ out->status = SCMI_SUCCESS;
+ }
+
+ return 0;
+}
+
+static int sandbox_scmi_clock_rate_get(struct udevice *dev,
+ struct scmi_msg *msg)
+{
+ struct sandbox_scmi_agent *agent = dev_get_priv(dev);
+ struct scmi_clk_rate_get_in *in = NULL;
+ struct scmi_clk_rate_get_out *out = NULL;
+ struct sandbox_scmi_clk *clk_state = NULL;
+
+ if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
+ !msg->out_msg || msg->out_msg_sz < sizeof(*out))
+ return -EINVAL;
+
+ in = (struct scmi_clk_rate_get_in *)msg->in_msg;
+ out = (struct scmi_clk_rate_get_out *)msg->out_msg;
+
+ clk_state = get_scmi_clk_state(agent->idx, in->clock_id);
+ if (!clk_state) {
+ dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);
+
+ out->status = SCMI_NOT_FOUND;
+ } else {
+ out->rate_msb = (u32)((u64)clk_state->rate >> 32);
+ out->rate_lsb = (u32)clk_state->rate;
+
+ out->status = SCMI_SUCCESS;
+ }
+
+ return 0;
+}
+
+static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg)
+{
+ struct sandbox_scmi_agent *agent = dev_get_priv(dev);
+ struct scmi_clk_state_in *in = NULL;
+ struct scmi_clk_state_out *out = NULL;
+ struct sandbox_scmi_clk *clk_state = NULL;
+
+ if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
+ !msg->out_msg || msg->out_msg_sz < sizeof(*out))
+ return -EINVAL;
+
+ in = (struct scmi_clk_state_in *)msg->in_msg;
+ out = (struct scmi_clk_state_out *)msg->out_msg;
+
+ clk_state = get_scmi_clk_state(agent->idx, in->clock_id);
+ if (!clk_state) {
+ dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);
+
+ out->status = SCMI_NOT_FOUND;
+ } else if (in->attributes > 1) {
+ out->status = SCMI_PROTOCOL_ERROR;
+ } else {
+ clk_state->enabled = in->attributes;
+
+ out->status = SCMI_SUCCESS;
+ }
+
+ return 0;
+}
+
static int sandbox_scmi_test_process_msg(struct udevice *dev,
struct scmi_msg *msg)
{
switch (msg->protocol_id) {
+ case SCMI_PROTOCOL_ID_CLOCK:
+ switch (msg->message_id) {
+ case SCMI_CLOCK_RATE_SET:
+ return sandbox_scmi_clock_rate_set(dev, msg);
+ case SCMI_CLOCK_RATE_GET:
+ return sandbox_scmi_clock_rate_get(dev, msg);
+ case SCMI_CLOCK_CONFIG_SET:
+ return sandbox_scmi_clock_gate(dev, msg);
+ default:
+ break;
+ }
+ break;
case SCMI_PROTOCOL_ID_BASE:
case SCMI_PROTOCOL_ID_POWER_DOMAIN:
case SCMI_PROTOCOL_ID_SYSTEM:
case SCMI_PROTOCOL_ID_PERF:
- case SCMI_PROTOCOL_ID_CLOCK:
case SCMI_PROTOCOL_ID_SENSOR:
case SCMI_PROTOCOL_ID_RESET_DOMAIN:
*(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED;
@@ -101,11 +258,15 @@ static int sandbox_scmi_test_probe(struct udevice *dev)
case '0':
*agent = (struct sandbox_scmi_agent){
.idx = 0,
+ .clk = scmi0_clk,
+ .clk_count = ARRAY_SIZE(scmi0_clk),
};
break;
case '1':
*agent = (struct sandbox_scmi_agent){
.idx = 1,
+ .clk = scmi1_clk,
+ .clk_count = ARRAY_SIZE(scmi1_clk),
};
break;
default:
diff --git a/drivers/firmware/scmi/sandbox-scmi_devices.c b/drivers/firmware/scmi/sandbox-scmi_devices.c
new file mode 100644
index 0000000000..b3e411c5ac
--- /dev/null
+++ b/drivers/firmware/scmi/sandbox-scmi_devices.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020, Linaro Limited
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/scmi_test.h>
+#include <dm/device_compat.h>
+
+/*
+ * Simulate to some extent a SCMI exchange.
+ * This drivers gets SCMI resources and offers API function to the
+ * SCMI test sequence manipulate the resources, currently clocks.
+ */
+
+#define SCMI_TEST_DEVICES_CLK_COUNT 3
+
+/*
+ * struct sandbox_scmi_device_priv - Storage for device handles used by test
+ * @clk: Array of clock instances used by tests
+ * @devices: Resources exposed by sandbox_scmi_devices_ctx()
+ */
+struct sandbox_scmi_device_priv {
+ struct clk clk[SCMI_TEST_DEVICES_CLK_COUNT];
+ struct sandbox_scmi_devices devices;
+};
+
+struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(struct udevice *dev)
+{
+ struct sandbox_scmi_device_priv *priv = dev_get_priv(dev);
+
+ if (priv)
+ return &priv->devices;
+
+ return NULL;
+}
+
+static int sandbox_scmi_devices_probe(struct udevice *dev)
+{
+ struct sandbox_scmi_device_priv *priv = dev_get_priv(dev);
+ int ret;
+ size_t n;
+
+ priv->devices = (struct sandbox_scmi_devices){
+ .clk = priv->clk,
+ .clk_count = SCMI_TEST_DEVICES_CLK_COUNT,
+ };
+
+ for (n = 0; n < SCMI_TEST_DEVICES_CLK_COUNT; n++) {
+ ret = clk_get_by_index(dev, n, priv->devices.clk + n);
+ if (ret) {
+ dev_err(dev, "%s: Failed on clk %zu\n", __func__, n);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const struct udevice_id sandbox_scmi_devices_ids[] = {
+ { .compatible = "sandbox,scmi-devices" },
+ { }
+};
+
+U_BOOT_DRIVER(sandbox_scmi_devices) = {
+ .name = "sandbox-scmi_devices",
+ .id = UCLASS_MISC,
+ .of_match = sandbox_scmi_devices_ids,
+ .priv_auto_alloc_size = sizeof(struct sandbox_scmi_device_priv),
+ .probe = sandbox_scmi_devices_probe,
+};
diff --git a/test/dm/scmi.c b/test/dm/scmi.c
index d8c1e71f12..aa46f31a47 100644
--- a/test/dm/scmi.c
+++ b/test/dm/scmi.c
@@ -13,26 +13,155 @@
*/
#include <common.h>
+#include <clk.h>
#include <dm.h>
#include <asm/scmi_test.h>
#include <dm/device-internal.h>
#include <dm/test.h>
+#include <linux/kconfig.h>
#include <test/ut.h>
+static int ut_assert_scmi_state_preprobe(struct unit_test_state *uts)
+{
+ struct sandbox_scmi_service *scmi_ctx = sandbox_scmi_service_ctx();
+
+ ut_assertnonnull(scmi_ctx);
+ if (scmi_ctx->agent_count)
+ ut_asserteq(2, scmi_ctx->agent_count);
+
+ return 0;
+}
+
+static int ut_assert_scmi_state_postprobe(struct unit_test_state *uts,
+ struct udevice *dev)
+{
+ struct sandbox_scmi_devices *scmi_devices;
+ struct sandbox_scmi_service *scmi_ctx;
+
+ /* Device references to check context against test sequence */
+ scmi_devices = sandbox_scmi_devices_ctx(dev);
+
+ ut_assertnonnull(scmi_devices);
+ if (IS_ENABLED(CONFIG_CLK_SCMI))
+ ut_asserteq(3, scmi_devices->clk_count);
+
+ /* State of the simulated SCMI server exposed */
+ scmi_ctx = sandbox_scmi_service_ctx();
+
+ ut_asserteq(2, scmi_ctx->agent_count);
+
+ ut_assertnonnull(scmi_ctx->agent[0]);
+ ut_asserteq(2, scmi_ctx->agent[0]->clk_count);
+ ut_assertnonnull(scmi_ctx->agent[0]->clk);
+
+ ut_assertnonnull(scmi_ctx->agent[1]);
+ ut_assertnonnull(scmi_ctx->agent[1]->clk);
+ ut_asserteq(1, scmi_ctx->agent[1]->clk_count);
+
+ return 0;
+}
+
+static int load_sandbox_scmi_test_devices(struct unit_test_state *uts,
+ struct udevice **dev)
+{
+ int ret;
+
+ ret = ut_assert_scmi_state_preprobe(uts);
+ if (ret)
+ return ret;
+
+ ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "sandbox_scmi",
+ dev));
+ ut_assertnonnull(*dev);
+
+ return ut_assert_scmi_state_postprobe(uts, *dev);
+}
+
+static int release_sandbox_scmi_test_devices(struct unit_test_state *uts,
+ struct udevice *dev)
+{
+ ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
+
+ /* Not sure test devices are fully removed, agent may not be visible */
+ return 0;
+}
+
/*
* Test SCMI states when loading and releasing resources
* related to SCMI drivers.
*/
static int dm_test_scmi_sandbox_agent(struct unit_test_state *uts)
{
- struct sandbox_scmi_service *scmi_ctx = sandbox_scmi_service_ctx();
+ struct udevice *dev = NULL;
+ int ret;
- ut_assertnonnull(scmi_ctx);
- ut_asserteq(2, scmi_ctx->agent_count);
- ut_assertnull(scmi_ctx->agent[0]);
- ut_assertnull(scmi_ctx->agent[1]);
+ ret = load_sandbox_scmi_test_devices(uts, &dev);
+ if (!ret)
+ ret = release_sandbox_scmi_test_devices(uts, dev);
- return 0;
+ return ret;
}
DM_TEST(dm_test_scmi_sandbox_agent, UT_TESTF_SCAN_FDT);
+
+static int dm_test_scmi_clocks(struct unit_test_state *uts)
+{
+ struct sandbox_scmi_devices *scmi_devices;
+ struct sandbox_scmi_service *scmi_ctx;
+ struct udevice *dev = NULL;
+ int ret_dev;
+ int ret;
+
+ if (!IS_ENABLED(CONFIG_CLK_SCMI))
+ return 0;
+
+ ret = load_sandbox_scmi_test_devices(uts, &dev);
+ if (ret)
+ return ret;
+
+ scmi_devices = sandbox_scmi_devices_ctx(dev);
+ scmi_ctx = sandbox_scmi_service_ctx();
+
+ /* Test SCMI clocks rate manipulation */
+ ut_asserteq(1000, clk_get_rate(&scmi_devices->clk[0]));
+ ut_asserteq(333, clk_get_rate(&scmi_devices->clk[1]));
+ ut_asserteq(44, clk_get_rate(&scmi_devices->clk[2]));
+
+ ret_dev = clk_set_rate(&scmi_devices->clk[1], 1088);
+ ut_assert(!ret_dev || ret_dev == 1088);
+
+ ut_asserteq(1000, scmi_ctx->agent[0]->clk[0].rate);
+ ut_asserteq(1088, scmi_ctx->agent[0]->clk[1].rate);
+ ut_asserteq(44, scmi_ctx->agent[1]->clk[0].rate);
+
+ ut_asserteq(1000, clk_get_rate(&scmi_devices->clk[0]));
+ ut_asserteq(1088, clk_get_rate(&scmi_devices->clk[1]));
+ ut_asserteq(44, clk_get_rate(&scmi_devices->clk[2]));
+
+ /* restore original rate for further tests */
+ ret_dev = clk_set_rate(&scmi_devices->clk[1], 333);
+ ut_assert(!ret_dev || ret_dev == 333);
+
+ /* Test SCMI clocks gating manipulation */
+ ut_assert(!scmi_ctx->agent[0]->clk[0].enabled);
+ ut_assert(!scmi_ctx->agent[0]->clk[1].enabled);
+ ut_assert(!scmi_ctx->agent[1]->clk[0].enabled);
+
+ ut_asserteq(0, clk_enable(&scmi_devices->clk[1]));
+ ut_asserteq(0, clk_enable(&scmi_devices->clk[2]));
+
+ ut_assert(!scmi_ctx->agent[0]->clk[0].enabled);
+ ut_assert(scmi_ctx->agent[0]->clk[1].enabled);
+ ut_assert(scmi_ctx->agent[1]->clk[0].enabled);
+
+ ut_assertok(clk_disable(&scmi_devices->clk[1]));
+ ut_assertok(clk_disable(&scmi_devices->clk[2]));
+
+ ut_assert(!scmi_ctx->agent[0]->clk[0].enabled);
+ ut_assert(!scmi_ctx->agent[0]->clk[1].enabled);
+ ut_assert(!scmi_ctx->agent[1]->clk[0].enabled);
+
+ return release_sandbox_scmi_test_devices(uts, dev);
+}
+
+DM_TEST(dm_test_scmi_clocks, UT_TESTF_SCAN_FDT);
--
2.17.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v4 6/8] firmware: scmi: sandbox test for SCMI clocks
2020-09-09 16:44 ` [PATCH v4 6/8] firmware: scmi: sandbox test for SCMI clocks Etienne Carriere
@ 2020-09-10 13:38 ` Simon Glass
2020-10-01 14:07 ` Tom Rini
1 sibling, 0 replies; 23+ messages in thread
From: Simon Glass @ 2020-09-10 13:38 UTC (permalink / raw)
To: u-boot
On Wed, 9 Sep 2020 at 10:44, Etienne Carriere
<etienne.carriere@linaro.org> wrote:
>
> Add tests for SCMI clocks. A test device driver sandbox-scmi_devices.c
> is used to get clock resources, allowing further clock manipulation.
>
> Change sandbox-smci_agent to emulate 3 clocks exposed through 2 agents.
> Add DM test scmi_clocks to test these 3 clocks.
> Update DM test sandbox_scmi_agent with load/remove test sequences
> factorized by {load|remove}_sandbox_scmi_test_devices() helper functions.
>
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> ---
>
> Changes in v4:
> - Move SCMI test devices instances from BSS to test device private data
> and update test/dm/scmi.c accordingly.
> - Update sandbox_scmi_devices_ctx() helper to add device reference arg.
> - Fix spelling issues in inline comments.
> - Rename local variables rc to ret for consistency.
>
> Changes in v3:
> - New commit in the series, addresses review comments on test support.
> ut_dm_scmi_clocks test SCMI are found and behave as expected for the
> implemented clk uclass methods.
> ---
> arch/sandbox/dts/test.dts | 15 ++
> arch/sandbox/include/asm/scmi_test.h | 39 +++++
> configs/sandbox_defconfig | 1 +
> drivers/firmware/scmi/Makefile | 2 +-
> drivers/firmware/scmi/sandbox-scmi_agent.c | 169 ++++++++++++++++++-
> drivers/firmware/scmi/sandbox-scmi_devices.c | 75 ++++++++
> test/dm/scmi.c | 141 +++++++++++++++-
> 7 files changed, 431 insertions(+), 11 deletions(-)
> create mode 100644 drivers/firmware/scmi/sandbox-scmi_devices.c
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 23+ messages in thread* [PATCH v4 6/8] firmware: scmi: sandbox test for SCMI clocks
2020-09-09 16:44 ` [PATCH v4 6/8] firmware: scmi: sandbox test for SCMI clocks Etienne Carriere
2020-09-10 13:38 ` Simon Glass
@ 2020-10-01 14:07 ` Tom Rini
1 sibling, 0 replies; 23+ messages in thread
From: Tom Rini @ 2020-10-01 14:07 UTC (permalink / raw)
To: u-boot
On Wed, Sep 09, 2020 at 06:44:05PM +0200, Etienne Carriere wrote:
> Add tests for SCMI clocks. A test device driver sandbox-scmi_devices.c
> is used to get clock resources, allowing further clock manipulation.
>
> Change sandbox-smci_agent to emulate 3 clocks exposed through 2 agents.
> Add DM test scmi_clocks to test these 3 clocks.
> Update DM test sandbox_scmi_agent with load/remove test sequences
> factorized by {load|remove}_sandbox_scmi_test_devices() helper functions.
>
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
Applied to u-boot/next, thanks!
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20201001/69f7622c/attachment.sig>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4 7/8] reset: add reset controller driver for SCMI agents
2020-09-09 16:44 [PATCH v4 1/8] firmware: add SCMI agent uclass Etienne Carriere
` (4 preceding siblings ...)
2020-09-09 16:44 ` [PATCH v4 6/8] firmware: scmi: sandbox test for SCMI clocks Etienne Carriere
@ 2020-09-09 16:44 ` Etienne Carriere
2020-09-10 13:38 ` Simon Glass
2020-10-01 14:08 ` Tom Rini
2020-09-09 16:44 ` [PATCH v4 8/8] firmware: smci: sandbox test for SCMI reset controllers Etienne Carriere
2020-10-01 14:07 ` [PATCH v4 1/8] firmware: add SCMI agent uclass Tom Rini
7 siblings, 2 replies; 23+ messages in thread
From: Etienne Carriere @ 2020-09-09 16:44 UTC (permalink / raw)
To: u-boot
This change introduces a reset controller driver for SCMI agent devices.
When SCMI agent and SCMI reset domain drivers are enabled, SCMI agent
binds a reset controller device for each SCMI reset domain protocol
devices enabled in the FDT.
SCMI reset driver is embedded upon CONFIG_RESET_SCMI=y. If enabled,
CONFIG_SCMI_AGENT is also enabled.
SCMI Reset Domain protocol is defined in the SCMI specification [1].
Links: [1] https://developer.arm.com/architectures/system-architectures/software-standards/scmi
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Cc: Simon Glass <sjg@chromium.org>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
---
Changes in v4:
- Condition DM_GET_DRIVER(scmi_reset_domain) to
IS_ENABLED(CONFIG_RESET_SCMI) to prevent a build error (linker) when
CONFIG_RESET_SCMI is disabled.
Changes in v3:
- Upgrade to rename into devm_scmi_process_msg() and scmi.h split
into scmi_*.h.
- Fix message ID used in scmi_reset_request().
Changes in v2:
- Change reset request() method to at least check the reset domain
exists by sending a SCMI RESET_DOMAIN_ATTRIBUTE message.
- Add inline description for the several structures.
- Patch v1 R-b tag not applied since the above changes in this v2.
BACKPORTED FROM v2020.10-rc2 to V2020.04
---
drivers/firmware/scmi/scmi_agent-uclass.c | 4 ++
drivers/reset/Kconfig | 8 +++
drivers/reset/Makefile | 1 +
drivers/reset/reset-scmi.c | 81 +++++++++++++++++++++++
include/scmi_protocols.h | 60 +++++++++++++++++
5 files changed, 154 insertions(+)
create mode 100644 drivers/reset/reset-scmi.c
diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c
index 1f36f23b6d..77160b1999 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -74,6 +74,10 @@ static int scmi_bind_protocols(struct udevice *dev)
if (IS_ENABLED(CONFIG_CLK_SCMI))
drv = DM_GET_DRIVER(scmi_clock);
break;
+ case SCMI_PROTOCOL_ID_RESET_DOMAIN:
+ if (IS_ENABLED(CONFIG_RESET_SCMI))
+ drv = DM_GET_DRIVER(scmi_reset_domain);
+ break;
default:
break;
}
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 253902ff57..ee5be0bc2f 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -173,4 +173,12 @@ config RESET_RASPBERRYPI
relevant. This driver provides a reset controller capable of
interfacing with RPi4's co-processor and model these firmware
initialization routines as reset lines.
+
+config RESET_SCMI
+ bool "Enable SCMI reset domain driver"
+ select SCMI_FIRMWARE
+ help
+ Enable this option if you want to support reset controller
+ devices exposed by a SCMI agent based on SCMI reset domain
+ protocol communication with a SCMI server.
endmenu
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 3c7f066ae3..625ec7168e 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
obj-$(CONFIG_RESET_SIFIVE) += reset-sifive.o
obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o
obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
+obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
diff --git a/drivers/reset/reset-scmi.c b/drivers/reset/reset-scmi.c
new file mode 100644
index 0000000000..1bff8075ee
--- /dev/null
+++ b/drivers/reset/reset-scmi.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019-2020 Linaro Limited
+ */
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <reset-uclass.h>
+#include <scmi_agent.h>
+#include <scmi_protocols.h>
+#include <asm/types.h>
+
+static int scmi_reset_set_level(struct reset_ctl *rst, bool assert_not_deassert)
+{
+ struct scmi_rd_reset_in in = {
+ .domain_id = rst->id,
+ .flags = assert_not_deassert ? SCMI_RD_RESET_FLAG_ASSERT : 0,
+ .reset_state = 0,
+ };
+ struct scmi_rd_reset_out out;
+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_RESET_DOMAIN,
+ SCMI_RESET_DOMAIN_RESET,
+ in, out);
+ int ret;
+
+ ret = devm_scmi_process_msg(rst->dev->parent, &msg);
+ if (ret)
+ return ret;
+
+ return scmi_to_linux_errno(out.status);
+}
+
+static int scmi_reset_assert(struct reset_ctl *rst)
+{
+ return scmi_reset_set_level(rst, true);
+}
+
+static int scmi_reset_deassert(struct reset_ctl *rst)
+{
+ return scmi_reset_set_level(rst, false);
+}
+
+static int scmi_reset_request(struct reset_ctl *rst)
+{
+ struct scmi_rd_attr_in in = {
+ .domain_id = rst->id,
+ };
+ struct scmi_rd_attr_out out;
+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_RESET_DOMAIN,
+ SCMI_RESET_DOMAIN_ATTRIBUTES,
+ in, out);
+ int ret;
+
+ /*
+ * We don't really care about the attribute, just check
+ * the reset domain exists.
+ */
+ ret = devm_scmi_process_msg(rst->dev->parent, &msg);
+ if (ret)
+ return ret;
+
+ return scmi_to_linux_errno(out.status);
+}
+
+static int scmi_reset_rfree(struct reset_ctl *rst)
+{
+ return 0;
+}
+
+static const struct reset_ops scmi_reset_domain_ops = {
+ .request = scmi_reset_request,
+ .rfree = scmi_reset_rfree,
+ .rst_assert = scmi_reset_assert,
+ .rst_deassert = scmi_reset_deassert,
+};
+
+U_BOOT_DRIVER(scmi_reset_domain) = {
+ .name = "scmi_reset_domain",
+ .id = UCLASS_RESET,
+ .ops = &scmi_reset_domain_ops,
+};
diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
index 4778bcfc47..ccab97c96c 100644
--- a/include/scmi_protocols.h
+++ b/include/scmi_protocols.h
@@ -116,4 +116,64 @@ struct scmi_clk_rate_set_out {
s32 status;
};
+/*
+ * SCMI Reset Domain Protocol
+ */
+
+enum scmi_reset_domain_message_id {
+ SCMI_RESET_DOMAIN_ATTRIBUTES = 0x3,
+ SCMI_RESET_DOMAIN_RESET = 0x4,
+};
+
+#define SCMI_RD_NAME_LEN 16
+
+#define SCMI_RD_ATTRIBUTES_FLAG_ASYNC BIT(31)
+#define SCMI_RD_ATTRIBUTES_FLAG_NOTIF BIT(30)
+
+#define SCMI_RD_RESET_FLAG_ASYNC BIT(2)
+#define SCMI_RD_RESET_FLAG_ASSERT BIT(1)
+#define SCMI_RD_RESET_FLAG_CYCLE BIT(0)
+
+/**
+ * struct scmi_rd_attr_in - Payload for RESET_DOMAIN_ATTRIBUTES message
+ * @domain_id: SCMI reset domain ID
+ */
+struct scmi_rd_attr_in {
+ u32 domain_id;
+};
+
+/**
+ * struct scmi_rd_attr_out - Payload for RESET_DOMAIN_ATTRIBUTES response
+ * @status: SCMI command status
+ * @attributes: Retrieved attributes of the reset domain
+ * @latency: Reset cycle max lantency
+ * @name: Reset domain name
+ */
+struct scmi_rd_attr_out {
+ s32 status;
+ u32 attributes;
+ u32 latency;
+ char name[SCMI_RD_NAME_LEN];
+};
+
+/**
+ * struct scmi_rd_reset_in - Message payload for RESET command
+ * @domain_id: SCMI reset domain ID
+ * @flags: Flags for the reset request
+ * @reset_state: Reset target state
+ */
+struct scmi_rd_reset_in {
+ u32 domain_id;
+ u32 flags;
+ u32 reset_state;
+};
+
+/**
+ * struct scmi_rd_reset_out - Response payload for RESET command
+ * @status: SCMI command status
+ */
+struct scmi_rd_reset_out {
+ s32 status;
+};
+
#endif /* _SCMI_PROTOCOLS_H */
--
2.17.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v4 7/8] reset: add reset controller driver for SCMI agents
2020-09-09 16:44 ` [PATCH v4 7/8] reset: add reset controller driver for SCMI agents Etienne Carriere
@ 2020-09-10 13:38 ` Simon Glass
2020-10-01 14:08 ` Tom Rini
1 sibling, 0 replies; 23+ messages in thread
From: Simon Glass @ 2020-09-10 13:38 UTC (permalink / raw)
To: u-boot
On Wed, 9 Sep 2020 at 10:44, Etienne Carriere
<etienne.carriere@linaro.org> wrote:
>
> This change introduces a reset controller driver for SCMI agent devices.
> When SCMI agent and SCMI reset domain drivers are enabled, SCMI agent
> binds a reset controller device for each SCMI reset domain protocol
> devices enabled in the FDT.
>
> SCMI reset driver is embedded upon CONFIG_RESET_SCMI=y. If enabled,
> CONFIG_SCMI_AGENT is also enabled.
>
> SCMI Reset Domain protocol is defined in the SCMI specification [1].
>
> Links: [1] https://developer.arm.com/architectures/system-architectures/software-standards/scmi
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> ---
>
> Changes in v4:
> - Condition DM_GET_DRIVER(scmi_reset_domain) to
> IS_ENABLED(CONFIG_RESET_SCMI) to prevent a build error (linker) when
> CONFIG_RESET_SCMI is disabled.
>
> Changes in v3:
> - Upgrade to rename into devm_scmi_process_msg() and scmi.h split
> into scmi_*.h.
> - Fix message ID used in scmi_reset_request().
>
> Changes in v2:
> - Change reset request() method to at least check the reset domain
> exists by sending a SCMI RESET_DOMAIN_ATTRIBUTE message.
> - Add inline description for the several structures.
> - Patch v1 R-b tag not applied since the above changes in this v2.
>
> BACKPORTED FROM v2020.10-rc2 to V2020.04
> ---
> drivers/firmware/scmi/scmi_agent-uclass.c | 4 ++
> drivers/reset/Kconfig | 8 +++
> drivers/reset/Makefile | 1 +
> drivers/reset/reset-scmi.c | 81 +++++++++++++++++++++++
> include/scmi_protocols.h | 60 +++++++++++++++++
> 5 files changed, 154 insertions(+)
> create mode 100644 drivers/reset/reset-scmi.c
>
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4 7/8] reset: add reset controller driver for SCMI agents
2020-09-09 16:44 ` [PATCH v4 7/8] reset: add reset controller driver for SCMI agents Etienne Carriere
2020-09-10 13:38 ` Simon Glass
@ 2020-10-01 14:08 ` Tom Rini
1 sibling, 0 replies; 23+ messages in thread
From: Tom Rini @ 2020-10-01 14:08 UTC (permalink / raw)
To: u-boot
On Wed, Sep 09, 2020 at 06:44:06PM +0200, Etienne Carriere wrote:
> This change introduces a reset controller driver for SCMI agent devices.
> When SCMI agent and SCMI reset domain drivers are enabled, SCMI agent
> binds a reset controller device for each SCMI reset domain protocol
> devices enabled in the FDT.
>
> SCMI reset driver is embedded upon CONFIG_RESET_SCMI=y. If enabled,
> CONFIG_SCMI_AGENT is also enabled.
>
> SCMI Reset Domain protocol is defined in the SCMI specification [1].
>
> Links: [1] https://developer.arm.com/architectures/system-architectures/software-standards/scmi
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
Applied to u-boot/next, thanks!
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20201001/f5f94383/attachment.sig>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4 8/8] firmware: smci: sandbox test for SCMI reset controllers
2020-09-09 16:44 [PATCH v4 1/8] firmware: add SCMI agent uclass Etienne Carriere
` (5 preceding siblings ...)
2020-09-09 16:44 ` [PATCH v4 7/8] reset: add reset controller driver for SCMI agents Etienne Carriere
@ 2020-09-09 16:44 ` Etienne Carriere
2020-09-10 13:38 ` Simon Glass
2020-10-01 14:08 ` Tom Rini
2020-10-01 14:07 ` [PATCH v4 1/8] firmware: add SCMI agent uclass Tom Rini
7 siblings, 2 replies; 23+ messages in thread
From: Etienne Carriere @ 2020-09-09 16:44 UTC (permalink / raw)
To: u-boot
Add tests for SCMI reset controllers. A test device driver
sandbox-scmi_devices.c is used to get reset resources, allowing further
resets manipulation.
Change sandbox-smci_agent to emulate 1 reset controller exposed through
an agent. Add DM test scmi_resets to test this reset controller.
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Cc: Simon Glass <sjg@chromium.org>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
---
Changes in v4:
- Rebase in the series without major conflict.
- Rename test/dm/scmi.c local variables rc to ret for consistency.
Changes in v3:
- New commit in the series, addresses review comments on test support.
ut_dm_scmi_resets() tests SCMI resources are found and behave as
expected for the implemented reset uclass methods.
---
arch/sandbox/dts/test.dts | 6 +
arch/sandbox/include/asm/scmi_test.h | 17 +++
configs/sandbox_defconfig | 1 +
drivers/firmware/scmi/sandbox-scmi_agent.c | 117 ++++++++++++++++++-
drivers/firmware/scmi/sandbox-scmi_devices.c | 40 ++++++-
test/dm/scmi.c | 36 ++++++
6 files changed, 211 insertions(+), 6 deletions(-)
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 61acd8d79f..7023f33a67 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -366,6 +366,11 @@
reg = <0x14>;
#clock-cells = <1>;
};
+
+ reset_scmi0: protocol at 16 {
+ reg = <0x16>;
+ #reset-cells = <1>;
+ };
};
sandbox-scmi-agent at 1 {
@@ -1065,6 +1070,7 @@
sandbox_scmi {
compatible = "sandbox,scmi-devices";
clocks = <&clk_scmi0 7>, <&clk_scmi0 3>, <&clk_scmi1 1>;
+ resets = <&reset_scmi0 3>;
};
pinctrl {
diff --git a/arch/sandbox/include/asm/scmi_test.h b/arch/sandbox/include/asm/scmi_test.h
index 63093fdb4d..3e8b0068fd 100644
--- a/arch/sandbox/include/asm/scmi_test.h
+++ b/arch/sandbox/include/asm/scmi_test.h
@@ -22,16 +22,29 @@ struct sandbox_scmi_clk {
ulong rate;
};
+/**
+ * struct sandbox_scmi_reset - Simulated reset controller exposed by SCMI
+ * @asserted: Reset control state: true if asserted, false if desasserted
+ */
+struct sandbox_scmi_reset {
+ uint id;
+ bool asserted;
+};
+
/**
* struct sandbox_scmi_agent - Simulated SCMI service seen by SCMI agent
* @idx: Identifier for the SCMI agent, its index
* @clk: Simulated clocks
* @clk_count: Simulated clocks array size
+ * @clk: Simulated reset domains
+ * @clk_count: Simulated reset domains array size
*/
struct sandbox_scmi_agent {
uint idx;
struct sandbox_scmi_clk *clk;
size_t clk_count;
+ struct sandbox_scmi_reset *reset;
+ size_t reset_count;
};
/**
@@ -48,10 +61,14 @@ struct sandbox_scmi_service {
* struct sandbox_scmi_devices - Reference to devices probed through SCMI
* @clk: Array the clock devices
* @clk_count: Number of clock devices probed
+ * @reset: Array the reset controller devices
+ * @reset_count: Number of reset controller devices probed
*/
struct sandbox_scmi_devices {
struct clk *clk;
size_t clk_count;
+ struct reset_ctl *reset;
+ size_t reset_count;
};
#ifdef CONFIG_SCMI_FIRMWARE
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 7d71c805dc..a2ebb3c971 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -220,6 +220,7 @@ CONFIG_REMOTEPROC_SANDBOX=y
CONFIG_DM_RESET=y
CONFIG_SANDBOX_RESET=y
CONFIG_RESET_SYSCON=y
+CONFIG_RESET_SCMI=y
CONFIG_DM_RNG=y
CONFIG_DM_RTC=y
CONFIG_RTC_RV8803=y
diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c b/drivers/firmware/scmi/sandbox-scmi_agent.c
index ff590988a6..5b6a4232af 100644
--- a/drivers/firmware/scmi/sandbox-scmi_agent.c
+++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
@@ -18,19 +18,20 @@
* processing. It simulates few of the SCMI services for some of the
* SCMI protocols embedded in U-Boot. Currently:
* - SCMI clock protocol: emulate 2 agents each exposing few clocks
+ * - SCMI reset protocol: emulate 1 agents each exposing a reset
*
- * Agent #0 simulates 2 clocks.
- * See IDs in scmi0_clk[] and "sandbox-scmi-agent at 0" in test.dts.
+ * Agent #0 simulates 2 clocks and 1 reset domain.
+ * See IDs in scmi0_clk[]/scmi0_reset[] and "sandbox-scmi-agent at 0" in test.dts.
*
* Agent #1 simulates 1 clock.
* See IDs in scmi1_clk[] and "sandbox-scmi-agent at 1" in test.dts.
*
- * All clocks are default disabled.
+ * All clocks are default disabled and reset levels down.
*
* This Driver exports sandbox_scmi_service_ct() for the test sequence to
* get the state of the simulated services (clock state, rate, ...) and
* check back-end device state reflects the request send through the
- * various uclass devices, currently only clock controllers.
+ * various uclass devices, as clocks and reset controllers.
*/
#define SANDBOX_SCMI_AGENT_COUNT 2
@@ -40,6 +41,10 @@ static struct sandbox_scmi_clk scmi0_clk[] = {
{ .id = 3, .rate = 333 },
};
+static struct sandbox_scmi_reset scmi0_reset[] = {
+ { .id = 3 },
+};
+
static struct sandbox_scmi_clk scmi1_clk[] = {
{ .id = 1, .rate = 44 },
};
@@ -71,6 +76,11 @@ static void debug_print_agent_state(struct udevice *dev, char *str)
agent->clk_count > 1 ? agent->clk[1].rate : -1,
agent->clk_count > 2 ? agent->clk[2].enabled : -1,
agent->clk_count > 2 ? agent->clk[2].rate : -1);
+ dev_dbg(dev, " scmi%u_reset (%zu): %d, %d, ...\n",
+ agent->idx,
+ agent->reset_count,
+ agent->reset_count ? agent->reset[0].asserted : -1,
+ agent->reset_count > 1 ? agent->reset[1].asserted : -1);
};
static struct sandbox_scmi_clk *get_scmi_clk_state(uint agent_id, uint clock_id)
@@ -99,6 +109,20 @@ static struct sandbox_scmi_clk *get_scmi_clk_state(uint agent_id, uint clock_id)
return NULL;
}
+static struct sandbox_scmi_reset *get_scmi_reset_state(uint agent_id,
+ uint reset_id)
+{
+ size_t n;
+
+ if (agent_id == 0) {
+ for (n = 0; n < ARRAY_SIZE(scmi0_reset); n++)
+ if (scmi0_reset[n].id == reset_id)
+ return scmi0_reset + n;
+ }
+
+ return NULL;
+}
+
/*
* Sandbox SCMI agent ops
*/
@@ -194,6 +218,78 @@ static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg)
return 0;
}
+static int sandbox_scmi_rd_attribs(struct udevice *dev, struct scmi_msg *msg)
+{
+ struct sandbox_scmi_agent *agent = dev_get_priv(dev);
+ struct scmi_rd_attr_in *in = NULL;
+ struct scmi_rd_attr_out *out = NULL;
+ struct sandbox_scmi_reset *reset_state = NULL;
+
+ if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
+ !msg->out_msg || msg->out_msg_sz < sizeof(*out))
+ return -EINVAL;
+
+ in = (struct scmi_rd_attr_in *)msg->in_msg;
+ out = (struct scmi_rd_attr_out *)msg->out_msg;
+
+ reset_state = get_scmi_reset_state(agent->idx, in->domain_id);
+ if (!reset_state) {
+ dev_err(dev, "Unexpected reset domain ID %u\n", in->domain_id);
+
+ out->status = SCMI_NOT_FOUND;
+ } else {
+ memset(out, 0, sizeof(*out));
+ snprintf(out->name, sizeof(out->name), "rd%u", in->domain_id);
+
+ out->status = SCMI_SUCCESS;
+ }
+
+ return 0;
+}
+
+static int sandbox_scmi_rd_reset(struct udevice *dev, struct scmi_msg *msg)
+{
+ struct sandbox_scmi_agent *agent = dev_get_priv(dev);
+ struct scmi_rd_reset_in *in = NULL;
+ struct scmi_rd_reset_out *out = NULL;
+ struct sandbox_scmi_reset *reset_state = NULL;
+
+ if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
+ !msg->out_msg || msg->out_msg_sz < sizeof(*out))
+ return -EINVAL;
+
+ in = (struct scmi_rd_reset_in *)msg->in_msg;
+ out = (struct scmi_rd_reset_out *)msg->out_msg;
+
+ reset_state = get_scmi_reset_state(agent->idx, in->domain_id);
+ if (!reset_state) {
+ dev_err(dev, "Unexpected reset domain ID %u\n", in->domain_id);
+
+ out->status = SCMI_NOT_FOUND;
+ } else if (in->reset_state > 1) {
+ dev_err(dev, "Invalid reset domain input attribute value\n");
+
+ out->status = SCMI_INVALID_PARAMETERS;
+ } else {
+ if (in->flags & SCMI_RD_RESET_FLAG_CYCLE) {
+ if (in->flags & SCMI_RD_RESET_FLAG_ASYNC) {
+ out->status = SCMI_NOT_SUPPORTED;
+ } else {
+ /* Ends deasserted whatever current state */
+ reset_state->asserted = false;
+ out->status = SCMI_SUCCESS;
+ }
+ } else {
+ reset_state->asserted = in->flags &
+ SCMI_RD_RESET_FLAG_ASSERT;
+
+ out->status = SCMI_SUCCESS;
+ }
+ }
+
+ return 0;
+}
+
static int sandbox_scmi_test_process_msg(struct udevice *dev,
struct scmi_msg *msg)
{
@@ -210,12 +306,21 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev,
break;
}
break;
+ case SCMI_PROTOCOL_ID_RESET_DOMAIN:
+ switch (msg->message_id) {
+ case SCMI_RESET_DOMAIN_ATTRIBUTES:
+ return sandbox_scmi_rd_attribs(dev, msg);
+ case SCMI_RESET_DOMAIN_RESET:
+ return sandbox_scmi_rd_reset(dev, msg);
+ default:
+ break;
+ }
+ break;
case SCMI_PROTOCOL_ID_BASE:
case SCMI_PROTOCOL_ID_POWER_DOMAIN:
case SCMI_PROTOCOL_ID_SYSTEM:
case SCMI_PROTOCOL_ID_PERF:
case SCMI_PROTOCOL_ID_SENSOR:
- case SCMI_PROTOCOL_ID_RESET_DOMAIN:
*(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED;
return 0;
default:
@@ -260,6 +365,8 @@ static int sandbox_scmi_test_probe(struct udevice *dev)
.idx = 0,
.clk = scmi0_clk,
.clk_count = ARRAY_SIZE(scmi0_clk),
+ .reset = scmi0_reset,
+ .reset_count = ARRAY_SIZE(scmi0_reset),
};
break;
case '1':
diff --git a/drivers/firmware/scmi/sandbox-scmi_devices.c b/drivers/firmware/scmi/sandbox-scmi_devices.c
index b3e411c5ac..c69967bf69 100644
--- a/drivers/firmware/scmi/sandbox-scmi_devices.c
+++ b/drivers/firmware/scmi/sandbox-scmi_devices.c
@@ -7,6 +7,7 @@
#include <clk.h>
#include <dm.h>
#include <malloc.h>
+#include <reset.h>
#include <asm/io.h>
#include <asm/scmi_test.h>
#include <dm/device_compat.h>
@@ -14,18 +15,22 @@
/*
* Simulate to some extent a SCMI exchange.
* This drivers gets SCMI resources and offers API function to the
- * SCMI test sequence manipulate the resources, currently clocks.
+ * SCMI test sequence manipulate the resources, currently clock
+ * and reset controllers.
*/
#define SCMI_TEST_DEVICES_CLK_COUNT 3
+#define SCMI_TEST_DEVICES_RD_COUNT 1
/*
* struct sandbox_scmi_device_priv - Storage for device handles used by test
* @clk: Array of clock instances used by tests
+ * @reset_clt: Array of the reset controller instances used by tests
* @devices: Resources exposed by sandbox_scmi_devices_ctx()
*/
struct sandbox_scmi_device_priv {
struct clk clk[SCMI_TEST_DEVICES_CLK_COUNT];
+ struct reset_ctl reset_ctl[SCMI_TEST_DEVICES_RD_COUNT];
struct sandbox_scmi_devices devices;
};
@@ -39,6 +44,22 @@ struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(struct udevice *dev)
return NULL;
}
+static int sandbox_scmi_devices_remove(struct udevice *dev)
+{
+ struct sandbox_scmi_devices *devices = sandbox_scmi_devices_ctx(dev);
+ int ret = 0;
+ size_t n;
+
+ for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) {
+ int ret2 = reset_free(devices->reset + n);
+
+ if (ret2 && !ret)
+ ret = ret2;
+ }
+
+ return ret;
+}
+
static int sandbox_scmi_devices_probe(struct udevice *dev)
{
struct sandbox_scmi_device_priv *priv = dev_get_priv(dev);
@@ -48,6 +69,8 @@ static int sandbox_scmi_devices_probe(struct udevice *dev)
priv->devices = (struct sandbox_scmi_devices){
.clk = priv->clk,
.clk_count = SCMI_TEST_DEVICES_CLK_COUNT,
+ .reset = priv->reset_ctl,
+ .reset_count = SCMI_TEST_DEVICES_RD_COUNT,
};
for (n = 0; n < SCMI_TEST_DEVICES_CLK_COUNT; n++) {
@@ -58,7 +81,21 @@ static int sandbox_scmi_devices_probe(struct udevice *dev)
}
}
+ for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) {
+ ret = reset_get_by_index(dev, n, priv->devices.reset + n);
+ if (ret) {
+ dev_err(dev, "%s: Failed on reset %zu\n", __func__, n);
+ goto err_reset;
+ }
+ }
+
return 0;
+
+err_reset:
+ for (; n > 0; n--)
+ reset_free(priv->devices.reset + n - 1);
+
+ return ret;
}
static const struct udevice_id sandbox_scmi_devices_ids[] = {
@@ -71,5 +108,6 @@ U_BOOT_DRIVER(sandbox_scmi_devices) = {
.id = UCLASS_MISC,
.of_match = sandbox_scmi_devices_ids,
.priv_auto_alloc_size = sizeof(struct sandbox_scmi_device_priv),
+ .remove = sandbox_scmi_devices_remove,
.probe = sandbox_scmi_devices_probe,
};
diff --git a/test/dm/scmi.c b/test/dm/scmi.c
index aa46f31a47..be60b44b3b 100644
--- a/test/dm/scmi.c
+++ b/test/dm/scmi.c
@@ -15,6 +15,7 @@
#include <common.h>
#include <clk.h>
#include <dm.h>
+#include <reset.h>
#include <asm/scmi_test.h>
#include <dm/device-internal.h>
#include <dm/test.h>
@@ -44,6 +45,8 @@ static int ut_assert_scmi_state_postprobe(struct unit_test_state *uts,
ut_assertnonnull(scmi_devices);
if (IS_ENABLED(CONFIG_CLK_SCMI))
ut_asserteq(3, scmi_devices->clk_count);
+ if (IS_ENABLED(CONFIG_RESET_SCMI))
+ ut_asserteq(1, scmi_devices->reset_count);
/* State of the simulated SCMI server exposed */
scmi_ctx = sandbox_scmi_service_ctx();
@@ -53,6 +56,8 @@ static int ut_assert_scmi_state_postprobe(struct unit_test_state *uts,
ut_assertnonnull(scmi_ctx->agent[0]);
ut_asserteq(2, scmi_ctx->agent[0]->clk_count);
ut_assertnonnull(scmi_ctx->agent[0]->clk);
+ ut_asserteq(1, scmi_ctx->agent[0]->reset_count);
+ ut_assertnonnull(scmi_ctx->agent[0]->reset);
ut_assertnonnull(scmi_ctx->agent[1]);
ut_assertnonnull(scmi_ctx->agent[1]->clk);
@@ -165,3 +170,34 @@ static int dm_test_scmi_clocks(struct unit_test_state *uts)
}
DM_TEST(dm_test_scmi_clocks, UT_TESTF_SCAN_FDT);
+
+static int dm_test_scmi_resets(struct unit_test_state *uts)
+{
+ struct sandbox_scmi_devices *scmi_devices;
+ struct sandbox_scmi_service *scmi_ctx;
+ struct udevice *dev = NULL;
+ int ret;
+
+ if (!IS_ENABLED(CONFIG_RESET_SCMI))
+ return 0;
+
+ ret = load_sandbox_scmi_test_devices(uts, &dev);
+ if (ret)
+ return ret;
+
+ scmi_devices = sandbox_scmi_devices_ctx(dev);
+ scmi_ctx = sandbox_scmi_service_ctx();
+
+ /* Test SCMI resect controller manipulation */
+ ut_assert(!scmi_ctx->agent[0]->reset[0].asserted)
+
+ ut_assertok(reset_assert(&scmi_devices->reset[0]));
+ ut_assert(scmi_ctx->agent[0]->reset[0].asserted)
+
+ ut_assertok(reset_deassert(&scmi_devices->reset[0]));
+ ut_assert(!scmi_ctx->agent[0]->reset[0].asserted);
+
+ return release_sandbox_scmi_test_devices(uts, dev);
+}
+
+DM_TEST(dm_test_scmi_resets, UT_TESTF_SCAN_FDT);
--
2.17.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v4 8/8] firmware: smci: sandbox test for SCMI reset controllers
2020-09-09 16:44 ` [PATCH v4 8/8] firmware: smci: sandbox test for SCMI reset controllers Etienne Carriere
@ 2020-09-10 13:38 ` Simon Glass
2020-10-01 14:08 ` Tom Rini
1 sibling, 0 replies; 23+ messages in thread
From: Simon Glass @ 2020-09-10 13:38 UTC (permalink / raw)
To: u-boot
On Wed, 9 Sep 2020 at 10:44, Etienne Carriere
<etienne.carriere@linaro.org> wrote:
>
> Add tests for SCMI reset controllers. A test device driver
> sandbox-scmi_devices.c is used to get reset resources, allowing further
> resets manipulation.
>
> Change sandbox-smci_agent to emulate 1 reset controller exposed through
> an agent. Add DM test scmi_resets to test this reset controller.
>
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> ---
>
> Changes in v4:
> - Rebase in the series without major conflict.
> - Rename test/dm/scmi.c local variables rc to ret for consistency.
>
> Changes in v3:
> - New commit in the series, addresses review comments on test support.
> ut_dm_scmi_resets() tests SCMI resources are found and behave as
> expected for the implemented reset uclass methods.
> ---
> arch/sandbox/dts/test.dts | 6 +
> arch/sandbox/include/asm/scmi_test.h | 17 +++
> configs/sandbox_defconfig | 1 +
> drivers/firmware/scmi/sandbox-scmi_agent.c | 117 ++++++++++++++++++-
> drivers/firmware/scmi/sandbox-scmi_devices.c | 40 ++++++-
> test/dm/scmi.c | 36 ++++++
> 6 files changed, 211 insertions(+), 6 deletions(-)
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4 8/8] firmware: smci: sandbox test for SCMI reset controllers
2020-09-09 16:44 ` [PATCH v4 8/8] firmware: smci: sandbox test for SCMI reset controllers Etienne Carriere
2020-09-10 13:38 ` Simon Glass
@ 2020-10-01 14:08 ` Tom Rini
1 sibling, 0 replies; 23+ messages in thread
From: Tom Rini @ 2020-10-01 14:08 UTC (permalink / raw)
To: u-boot
On Wed, Sep 09, 2020 at 06:44:07PM +0200, Etienne Carriere wrote:
> Add tests for SCMI reset controllers. A test device driver
> sandbox-scmi_devices.c is used to get reset resources, allowing further
> resets manipulation.
>
> Change sandbox-smci_agent to emulate 1 reset controller exposed through
> an agent. Add DM test scmi_resets to test this reset controller.
>
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
Applied to u-boot/next, thanks!
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20201001/ad69d3a8/attachment.sig>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v4 1/8] firmware: add SCMI agent uclass
2020-09-09 16:44 [PATCH v4 1/8] firmware: add SCMI agent uclass Etienne Carriere
` (6 preceding siblings ...)
2020-09-09 16:44 ` [PATCH v4 8/8] firmware: smci: sandbox test for SCMI reset controllers Etienne Carriere
@ 2020-10-01 14:07 ` Tom Rini
7 siblings, 0 replies; 23+ messages in thread
From: Tom Rini @ 2020-10-01 14:07 UTC (permalink / raw)
To: u-boot
On Wed, Sep 09, 2020 at 06:44:00PM +0200, Etienne Carriere wrote:
> This change introduces SCMI agent uclass to interact with a firmware
> using the SCMI protocols [1].
>
> SCMI agent uclass currently supports a single method to request
> processing of the SCMI message by an identified server. A SCMI message
> is made of a byte payload associated to a protocol ID and a message ID,
> all defined by the SCMI specification [1]. On return from process_msg()
> method, the caller gets the service response.
>
> SCMI agent uclass defines a post bind generic sequence for all devices.
> The sequence binds all the SCMI protocols listed in the FDT for that
> SCMI agent device. Currently none, but later change will introduce
> protocols.
>
> This change implements a simple sandbox device for the SCMI agent uclass.
> The sandbox nicely answers SCMI_NOT_SUPPORTED to SCMI messages.
> To prepare for further test support, the sandbox exposes a architecture
> function for test application to read the sandbox emulated devices state.
> Currently supports 2 SCMI agents, identified by an ID in the FDT device
> name. The simplistic DM test does nothing yet.
>
> SCMI agent uclass is designed for platforms that embed a SCMI server in
> a firmware hosted somewhere, for example in a companion co-processor or
> in the secure world of the executing processor. SCMI protocols allow an
> SCMI agent to discover and access external resources as clock, reset
> controllers and more. SCMI agent and server communicate following the
> SCMI specification [1]. This SCMI agent implementation complies with
> the DT bindings defined in the Linux kernel source tree regarding
> SCMI agent description since v5.8.
>
> Links: [1] https://developer.arm.com/architectures/system-architectures/software-standards/scmi
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
Applied to u-boot/next, thanks!
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20201001/5063fe28/attachment.sig>
^ permalink raw reply [flat|nested] 23+ messages in thread