From patchwork Tue Aug 18 15:41:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Etienne Carriere X-Patchwork-Id: 247898 Delivered-To: patch@linaro.org Received: by 2002:a54:3b12:0:0:0:0:0 with SMTP id j18csp3230665ect; Tue, 18 Aug 2020 08:45:10 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzYD6hZIw0W5N0Toh6Gsr6lE5++973Rxu22LCHi9Pq7+l3Ymg6VV+T02LjbaMlz2aW9JyZp X-Received: by 2002:a17:906:6d54:: with SMTP id a20mr21812512ejt.501.1597765510476; Tue, 18 Aug 2020 08:45:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597765510; cv=none; d=google.com; s=arc-20160816; b=h8i/e60+JkrfHEoz5/Q621JiOYaNSnXcIceV6Mt6aG929npyO3bYfPHLHZxITIUUs3 UXw8NylPqYQ0AhQSzmFQCqLury1yJ5LyxEv21HGHi/o1JgXW+Sj6tt3GZkfbiLOyq2wS mKeydIQLVkZobzeqOSwM2vCov90TG3qMM02ZnJhlySOO79d7bKsekDNU2c2yIthpMbRH GahQqrTwQNU/NDwOerbKViMLOTitI7j4fZ8uS2kIV07fO3HZQ6m7BZCsYLaOSozNjfQl IV5Q9HTUPCKN2nTviDEfqeYyXn2Sg/g/K19bIKbUYqFFlyUddx18HJaOp8YhcEphFsHm WqfQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:message-id:date:subject:cc:to :from:dkim-signature; bh=Y5LHXP/7uhsD3rM6JiZqmRrEbJHgLC2U48og+9MFc2w=; b=X4lrSMwt6SYK7fM5yLmatQIwHWOrc3C8n9bb5DSzuKKOCn1PKlRlhfW0pAwEXJVBdO 1Ex2FWsqkirMUTlC1O8OBtf9KsZC0RMBtSaOd1vSKE1p+bC4pWpP5f+37YFQ9xJNVhQh PQqKI6bLkQl72fMnr4IVDbx7SY37fzlYOfY1emnFTbdMCl+SgTmo/R3HVrw6Qp8TOQg1 vJEYPKrl7O7e/EIFSWLBMTOS7khzHO/ueqdAWY9Zdfw5GncpeEre9/CQIgQ52gx2ut+4 c41/yhS4Mqxk42dFKCBp8Mzc3YP15MO4+3Sz7g+Y69kyCXB+xQKp6ixG8u+cllzG1Urq 4vzQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="fYp/adqG"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id si30si13829313ejb.569.2020.08.18.08.45.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Aug 2020 08:45:10 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="fYp/adqG"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 90EBE821AF; Tue, 18 Aug 2020 17:45:00 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="fYp/adqG"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id F1793821F7; Tue, 18 Aug 2020 17:44:58 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wm1-x344.google.com (mail-wm1-x344.google.com [IPv6:2a00:1450:4864:20::344]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 2D57481C17 for ; Tue, 18 Aug 2020 17:44:55 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=etienne.carriere@linaro.org Received: by mail-wm1-x344.google.com with SMTP id 9so16661247wmj.5 for ; Tue, 18 Aug 2020 08:44:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=Y5LHXP/7uhsD3rM6JiZqmRrEbJHgLC2U48og+9MFc2w=; b=fYp/adqGnQvzXjfFdc1eF0xOLZ0OwuQuRX4PSF88QyYftFiOvKD2f6wb7gzTNRTZiz P0kV5yD0fUUC/29NSz/PqhAhRuMgmrh9X+6g5KpMivq7tknglWCDTBT4fxkCA1gutvC3 XTN97dF3xEBRC+ilUw3inat7vPdgFq1MgjERr9DCklOgdjNfC/5diRrZdqQ09KbqUaI4 SGU7j8xFe9gUvdlg22KmtLgnEfu6FfgLIL0FMvP5FxZ5ATr8KbwAHSPZRnebLqS/CpFI p8KKIeGtHqaSUHnuXbPpY6iWOoHPQib3kka7B5ZzXZcmzTSYwbym08JV9gbN58HdmceD zz2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=Y5LHXP/7uhsD3rM6JiZqmRrEbJHgLC2U48og+9MFc2w=; b=WYsZQ/BX5kivYbx+EJ6LrqZlfgU+MFMTgbrcjP53uiHgXsWz/MRBm8BmNc27B98wEC mPXGaOZOTwoFaxY/GACbmfCP4o82d6uJyB7KY4au8tD157OnuyE7rxWChcbnPNzR7eWY HtD7LtvymYsiaK9hs8egVz4J3pkkzsFfDUxH+owBaus2DXuK19DOAQdp0ErtWpfsM8ks CoyPj0VrS3XQGVbpxjrvbwdSpHthm1ei8iqPlRy6EOvWEd4mUeFmf29pduM9l7kVVtmy sxW3OZTqkkulSIr8P+H44/7p+KaKlHqlQ91micJa04qw+lvZItSIYEaflsKsNIcOJS9p vIlQ== X-Gm-Message-State: AOAM530fzMk422j7G7F9M2sLkghbBuYsFwAAJ0wrBi0d5+Cro3ZIt9Se Frn8EoOYsLbyAECRwitf2H2lqjroRVm36T5v X-Received: by 2002:a05:600c:21cd:: with SMTP id x13mr508344wmj.155.1597765494248; Tue, 18 Aug 2020 08:44:54 -0700 (PDT) Received: from lmecxl0524.lme.st.com ([2a04:cec0:11d8:1838:f15d:dd00:3cff:c56f]) by smtp.gmail.com with ESMTPSA id h11sm35772645wrb.68.2020.08.18.08.44.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Aug 2020 08:44:53 -0700 (PDT) From: Etienne Carriere To: u-boot@lists.denx.de Cc: Etienne Carriere , Simon Glass , Peng Fan , Sudeep Holla Subject: [PATCH v2 1/4] firmware: add new driver for SCMI firmwares Date: Tue, 18 Aug 2020 17:41:30 +0200 Message-Id: <20200818154133.22028-1-etienne.carriere@linaro.org> X-Mailer: git-send-email 2.17.1 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean This change introduces SCMI agent driver in U-Boot in the firmware U-class. SCMI agent driver is designed for platforms that embed a SCMI server in a firmware hosted for example by a companion co-processor or the secure world of the executing processor. SCMI protocols allow an SCMI agent to discover and access external resources as clock, reset controllers and many more. SCMI agent and server communicate following the SCMI specification [1]. SCMI agent complies with the DT bindings defined in the Linux kernel source tree regarding SCMI agent description since v5.8-rc1. These bindings describe 2 supported message transport layer: using mailbox uclass devices or using Arm SMC invocation instruction. Both use a piece or shared memory for message data exchange. In the current state, the SCMI agent driver does not bind to any SCMI protocol to a U-Boot device driver. Former changes will implement dedicated driver (i.e. an SCMI clock driver or an SCMI reset controller driver) and add bind supported SCMI protocols in scmi_agent_bind(). Links: [1] https://developer.arm.com/architectures/system-architectures/software-standards/scmi Signed-off-by: Etienne Carriere Cc: Simon Glass Cc: Peng Fan Cc: Sudeep Holla --- Changes in v2: - Fix CONFIG_SCMI_FIRMWARE description with explicit SCMI reference. - Move struct, enum and macro definitions at source file top and add inline comment description for the structures and local functions. - Replace rc with ret as return value local variable label. - Use explicit return 0 on successful return paths. - Replace EINVAL with more accurate error numbers. - Use dev_read_u32() instead of ofnode_read_u32(dev_ofnode(), ...). - Use memcpy_toio()/memcpy_fromio() when copying message payload to/from IO memory. - Embed mailbox transport resources upon CONFIG_DM_MAILBOX and SMCCC transport resources upon CONFIG_ARM_SMCCC. Note: review comments on defining a uclass and sandbox for SCMI transport drivers are NOT addressed in this v2. Main issue is that there is no driver/device defined for SCMI transport layer as well as and no defined compatible ID in the SCMI DT bindings documentation. --- drivers/firmware/Kconfig | 20 ++ drivers/firmware/Makefile | 1 + drivers/firmware/scmi.c | 490 ++++++++++++++++++++++++++++++++++++++ include/scmi.h | 82 +++++++ 4 files changed, 593 insertions(+) create mode 100644 drivers/firmware/scmi.c create mode 100644 include/scmi.h -- 2.17.1 diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index b70a206355..4d3cd5c6f2 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -1,6 +1,26 @@ config FIRMWARE bool "Enable Firmware driver support" +config SCMI_FIRMWARE + bool "Enable SCMI support" + select FIRMWARE + select OF_TRANSLATE + depends on DM_MAILBOX || ARM_SMCCC + help + System Control and Management Interface (SCMI) is a communication + protocol that defines standard interfaces for power, performance + and system management. The SCMI specification is available at + https://developer.arm.com/architectures/system-architectures/software-standards/scmi + + An SCMI agent communicates with a related SCMI server firmware + located in another sub-system, as a companion micro controller + or a companion host in the CPU system. + + Communications between agent (client) and the SCMI server are + based on message exchange. Messages can be exchange over tranport + channels as a mailbox device or an Arm SMCCC service with some + piece of identified shared memory. + config SPL_FIRMWARE bool "Enable Firmware driver support in SPL" depends on FIRMWARE diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index a0c250a473..9d16055510 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -2,4 +2,5 @@ obj-$(CONFIG_FIRMWARE) += firmware-uclass.o obj-$(CONFIG_$(SPL_)ARM_PSCI_FW) += psci.o obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o obj-$(CONFIG_SANDBOX) += firmware-sandbox.o +obj-$(CONFIG_SCMI_FIRMWARE) += scmi.o obj-$(CONFIG_ZYNQMP_FIRMWARE) += firmware-zynqmp.o diff --git a/drivers/firmware/scmi.c b/drivers/firmware/scmi.c new file mode 100644 index 0000000000..264f3d99c8 --- /dev/null +++ b/drivers/firmware/scmi.c @@ -0,0 +1,490 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (C) 2019-2020 Linaro Limited. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TIMEOUT_US_10MS 10000 + +/** + * enum scmi_transport_channel - Supported SCMI transport layers + */ +enum scmi_transport_channel { + SCMI_MAILBOX_TRANSPORT, + SCMI_ARM_SMCCC_TRANSPORT, +}; + +/** + * struct error_code - Helper structure for SCMI error code conversion + * @scmi: SCMI error code + * @errno: Related standard error number + */ +struct error_code { + int scmi; + int errno; +}; + +/** + * struct method_ops - Operations related to an SCMI transport layer + * @process_msg: Send message thru the SCMI transport + * @remove_agent: Release SCMI transport resource + */ +struct method_ops { + int (*process_msg)(struct udevice *dev, struct scmi_msg *msg); + int (*remove_agent)(struct udevice *dev); +}; + +/** + * struct scmi_agent - Description of SCMI agent transport layer + * @method_ops: Operations for the transport layer used the agent + * @method_priv: Private data for the transport layer used the agent + */ +struct scmi_agent { + struct method_ops *method_ops; + void *method_priv; +}; + +/** + * 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_shm_buf - Description of a shared memory buffer + * @buf: Shared memory base address + * @size: Shared memory byte size + */ +struct scmi_shm_buf { + u8 *buf; + size_t size; +}; + +/** + * struct scmi_mbox_channel - Description of an SCMI mailbox transport + * @shm_buf: Shared memory buffer + * @mbox: Mailbox channel description + * @timeout_us: Timeout in microseconds for the mailbox transfer + */ +struct scmi_mbox_channel { + struct scmi_shm_buf shm_buf; + struct mbox_chan mbox; + ulong timeout_us; +}; + +/** + * struct scmi_arm_smc_channel - Description of an SCMI SMCCC transport + * @func_id: SMCCC function ID used by the SCMI transport + * @shm_buf: Shared memory buffer + */ +struct scmi_arm_smc_channel { + ulong func_id; + struct scmi_shm_buf shm_buf; +}; + +static const struct error_code scmi_linux_errmap[] = { + { .scmi = SCMI_NOT_SUPPORTED, .errno = -EOPNOTSUPP, }, + { .scmi = SCMI_INVALID_PARAMETERS, .errno = -EINVAL, }, + { .scmi = SCMI_DENIED, .errno = -EACCES, }, + { .scmi = SCMI_NOT_FOUND, .errno = -ENOENT, }, + { .scmi = SCMI_OUT_OF_RANGE, .errno = -ERANGE, }, + { .scmi = SCMI_BUSY, .errno = -EBUSY, }, + { .scmi = SCMI_COMMS_ERROR, .errno = -ECOMM, }, + { .scmi = SCMI_GENERIC_ERROR, .errno = -EIO, }, + { .scmi = SCMI_HARDWARE_ERROR, .errno = -EREMOTEIO, }, + { .scmi = SCMI_PROTOCOL_ERROR, .errno = -EPROTO, }, +}; + +int scmi_to_linux_errno(s32 scmi_code) +{ + int n; + + if (!scmi_code) + return 0; + + for (n = 0; n < ARRAY_SIZE(scmi_linux_errmap); n++) + if (scmi_code == scmi_linux_errmap[n].scmi) + return scmi_linux_errmap[1].errno; + + return -EPROTO; +} + +/** + * Get shared memory configuration defined by the referred DT phandle + * Return with a errno compliant value. + */ +static int get_shm_buffer(struct udevice *dev, struct scmi_shm_buf *shm) +{ + 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); + + shm->size = resource_size(&resource); + if (shm->size < sizeof(struct scmi_smt_header)) { + dev_err(dev, "Shared memory buffer too small\n"); + return -EINVAL; + } + + shm->buf = devm_ioremap(dev, paddr, shm->size); + if (!shm->buf) + return -ENOMEM; + + if (dcache_status()) + mmu_set_region_dcache_behaviour((uintptr_t)shm->buf, + shm->size, DCACHE_OFF); + + return 0; +} + +/** + * Write SCMI message @msg into a SMT shared buffer @shm_buf. + * Return 0 on success and with a negative errno in case of error. + */ +static int write_msg_to_smt(struct udevice *dev, struct scmi_shm_buf *shm_buf, + struct scmi_msg *msg) +{ + struct scmi_smt_header *hdr = (void *)shm_buf->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 (shm_buf->size < (sizeof(*hdr) + msg->in_msg_sz) || + shm_buf->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 @shm_buf and copy it into @msg. + * Return 0 on success and with a negative errno in case of error. + */ +static int read_resp_from_smt(struct udevice *dev, struct scmi_shm_buf *shm_buf, + struct scmi_msg *msg) +{ + struct scmi_smt_header *hdr = (void *)shm_buf->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 + */ +static void clear_smt_channel(struct scmi_shm_buf *shm_buf) +{ + struct scmi_smt_header *hdr = (void *)shm_buf->buf; + + hdr->channel_status &= ~SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR; +} + +#ifdef CONFIG_DM_MAILBOX +/* + * SCMI over mailbox transport + */ + +static int mbox_process_msg(struct udevice *dev, struct scmi_msg *msg) +{ + struct scmi_agent *agent = dev_get_priv(dev); + struct scmi_mbox_channel *chan = agent->method_priv; + int ret; + + ret = write_msg_to_smt(dev, &chan->shm_buf, msg); + if (ret) + return ret; + + /* Give shm addr to mbox in case it is meaningful */ + ret = mbox_send(&chan->mbox, chan->shm_buf.buf); + if (ret) { + dev_err(dev, "Message send failed: %d\n", ret); + goto out; + } + + /* Receive the response */ + ret = mbox_recv(&chan->mbox, chan->shm_buf.buf, chan->timeout_us); + if (ret) { + dev_err(dev, "Response failed: %d, abort\n", ret); + goto out; + } + + ret = read_resp_from_smt(dev, &chan->shm_buf, msg); + +out: + clear_smt_channel(&chan->shm_buf); + + return ret; +} + +struct method_ops mbox_channel_ops = { + .process_msg = mbox_process_msg, +}; + +static int probe_mailbox_channel(struct udevice *dev) +{ + struct scmi_agent *agent = dev_get_priv(dev); + struct scmi_mbox_channel *chan; + int ret; + + chan = devm_kzalloc(dev, sizeof(*chan), GFP_KERNEL); + if (!chan) + return -ENOMEM; + + 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 = get_shm_buffer(dev, &chan->shm_buf); + if (ret) + dev_err(dev, "Failed to get shm resources: %d\n", ret); + +out: + if (ret) { + devm_kfree(dev, chan); + return ret; + } + + agent->method_ops = &mbox_channel_ops; + agent->method_priv = (void *)chan; + + return 0; +} +#endif /* CONFIG_DM_MAILBOX */ + +#ifdef CONFIG_ARM_SMCCC +/* + * SCMI over SMCCC transport + */ + +#define SMCCC_RET_NOT_SUPPORTED ((unsigned long)-1) + +static int arm_smc_process_msg(struct udevice *dev, struct scmi_msg *msg) +{ + struct scmi_agent *agent = dev_get_priv(dev); + struct scmi_arm_smc_channel *chan = agent->method_priv; + struct arm_smccc_res res; + int ret; + + ret = write_msg_to_smt(dev, &chan->shm_buf, 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 = read_resp_from_smt(dev, &chan->shm_buf, msg); + + clear_smt_channel(&chan->shm_buf); + + return ret; +} + +struct method_ops arm_smc_channel_ops = { + .process_msg = arm_smc_process_msg, +}; + +static int probe_arm_smc_channel(struct udevice *dev) +{ + struct scmi_agent *agent = dev_get_priv(dev); + struct scmi_arm_smc_channel *chan; + u32 func_id; + int ret; + + chan = devm_kzalloc(dev, sizeof(*chan), GFP_KERNEL); + if (!chan) + return -ENOMEM; + + 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 = get_shm_buffer(dev, &chan->shm_buf); + if (ret) { + dev_err(dev, "Failed to get shm resources: %d\n", ret); + return ret; + } + + agent->method_ops = &arm_smc_channel_ops; + agent->method_priv = (void *)chan; + + return 0; +} +#endif /* CONFIG_ARM_SMCCC */ + +int scmi_send_and_process_msg(struct udevice *dev, struct scmi_msg *msg) +{ + struct scmi_agent *agent = dev_get_priv(dev); + + return agent->method_ops->process_msg(dev, msg); +} + +static int scmi_remove(struct udevice *dev) +{ + struct scmi_agent *agent = dev_get_priv(dev); + + if (agent->method_ops->remove_agent) + return agent->method_ops->remove_agent(dev); + + return 0; +} + +static int scmi_probe(struct udevice *dev) +{ + switch (dev_get_driver_data(dev)) { + case SCMI_MAILBOX_TRANSPORT: + if (IS_ENABLED(CONFIG_DM_MAILBOX)) + return probe_mailbox_channel(dev); + break; + case SCMI_ARM_SMCCC_TRANSPORT: + if (IS_ENABLED(CONFIG_ARM_SMCCC)) + return probe_arm_smc_channel(dev); + break; + default: + break; + } + + return -ENOENT; +} + +static int scmi_bind(struct udevice *dev) +{ + int ret = 0; + ofnode node; + struct driver *drv; + + dev_for_each_subnode(node, dev) { + u32 protocol_id; + + if (!ofnode_is_available(node)) + continue; + + if (ofnode_read_u32(node, "reg", &protocol_id)) + continue; + + switch (protocol_id) { + default: + dev_info(dev, "Ignore unsupported SCMI protocol %u\n", + protocol_id); + continue; + } + + ret = device_bind_ofnode(dev, drv, ofnode_get_name(node), + NULL, node, NULL); + if (ret) + break; + } + + return ret; +} + +static const struct udevice_id scmi_ids[] = { + { .compatible = "arm,scmi", .data = SCMI_MAILBOX_TRANSPORT }, + { .compatible = "arm,scmi-smc", .data = SCMI_ARM_SMCCC_TRANSPORT }, + { } +}; + +U_BOOT_DRIVER(scmi) = { + .name = "scmi", + .id = UCLASS_FIRMWARE, + .of_match = scmi_ids, + .priv_auto_alloc_size = sizeof(struct scmi_agent), + .bind = scmi_bind, + .probe = scmi_probe, + .remove = scmi_remove, + .flags = DM_FLAG_OS_PREPARE, +}; diff --git a/include/scmi.h b/include/scmi.h new file mode 100644 index 0000000000..a75d38916d --- /dev/null +++ b/include/scmi.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (C) 2019, Linaro Limited + */ +#ifndef SCMI_H +#define SCMI_H + +#include + +/** + * An SCMI agent represent on communication path from a device driver to + * the remote SCMI server which driver sends messages to and receives + * response messages from. + */ +struct scmi_agent; + +enum scmi_std_protocol { + SCMI_PROTOCOL_ID_BASE = 0x10, + SCMI_PROTOCOL_ID_POWER_DOMAIN = 0x11, + SCMI_PROTOCOL_ID_SYSTEM = 0x12, + SCMI_PROTOCOL_ID_PERF = 0x13, + SCMI_PROTOCOL_ID_CLOCK = 0x14, + SCMI_PROTOCOL_ID_SENSOR = 0x15, + SCMI_PROTOCOL_ID_RESET_DOMAIN = 0x16, +}; + +enum scmi_status_code { + SCMI_SUCCESS = 0, + SCMI_NOT_SUPPORTED = -1, + SCMI_INVALID_PARAMETERS = -2, + SCMI_DENIED = -3, + SCMI_NOT_FOUND = -4, + SCMI_OUT_OF_RANGE = -5, + SCMI_BUSY = -6, + SCMI_COMMS_ERROR = -7, + SCMI_GENERIC_ERROR = -8, + SCMI_HARDWARE_ERROR = -9, + SCMI_PROTOCOL_ERROR = -10, +}; + +/* + * struct scmi_msg - Context of a SCMI message sent and the response received + * + * @protocol_id: SCMI protocol ID + * @message_id: SCMI message ID for a defined protocol ID + * @in_msg: Pointer to the message payload sent by the driver + * @in_msg_sz: Byte size of the message payload sent + * @out_msg: Pointer to buffer to store response message payload + * @out_msg_sz: Byte size of the response buffer or payload + */ +struct scmi_msg { + unsigned int protocol_id; + unsigned int message_id; + u8 *in_msg; + size_t in_msg_sz; + u8 *out_msg; + size_t out_msg_sz; +}; + +/** + * scmi_send_and_process_msg() - send and process a SCMI message + * + * Send a message to a SCMI server through a target SCMI agent device. + * Caller sets scmi_msg::out_msg_sz to the output message buffer size. + * On return, scmi_msg::out_msg_sz stores the response payload size. + * + * @dev: SCMI agent device + * @msg: Message structure reference + * @return 0 on success, a negative errno otherwise + */ +int scmi_send_and_process_msg(struct udevice *dev, struct scmi_msg *msg); + +/** + * scmi_to_linux_errno() - Convert an SCMI error code into a Linux errno code + * + * @scmi_errno: SCMI error code value + * @return 0 for successful status and a negative errno otherwise + */ +int scmi_to_linux_errno(s32 scmi_errno); + +#endif /* SCMI_H */ From patchwork Tue Aug 18 15:41:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Etienne Carriere X-Patchwork-Id: 247899 Delivered-To: patch@linaro.org Received: by 2002:a54:3b12:0:0:0:0:0 with SMTP id j18csp3230756ect; Tue, 18 Aug 2020 08:45:18 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwr6vlDYPII+d9WPmXAv4DvKk+4jz4kfaKmWeskPmj6qh32nulEIULkcT4YhpHVKIYMJ3uC X-Received: by 2002:a05:6402:33a:: with SMTP id q26mr21569048edw.8.1597765518696; Tue, 18 Aug 2020 08:45:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597765518; cv=none; d=google.com; s=arc-20160816; b=MmWEdtrc+M9yoI2uSZju7A1S9iYPL0OBvPbSafr6CAPEO0sb6Ja66ruUrV453QfQE/ JxC+ltFyN8rj+diGrJNR9HtTX8ibThgulRl9GnzhvTNjJsrNDBeegujB1NS1v7KG0Fmk c5pqly74c3Y5Udi63C8+iwIsAO/B0ed2kN70nAWIhUnsIiHmIsrmnNA3V9/1TrugnwUT 0Q1/LV0UkJhKFePMjN6Gntll70/al6DQ2ZHqy3EUMh+hgQFuuLu1qE3o6xbF01FyVZ70 DB5b1VYJDyrrlUgN270zRBpKmNh5QsJOzfz0h66CVcc85N2ZY4NDOCVJbGuDCiCiRtZV KR+w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=R78OpiNxqITlOP90Ir31jN3cIvMlK93IuJHKOIFXF/A=; b=OZWwXVhZwUNy5+OxI0gFZ1lMiqHWstLlVqAhuAgPXIrk+1eWz2mHMEaOfLmTjulUCa TExV8SBikuCjgdR8RyOAndjznWBcFyu8W5STlrxLoAqG8egITiGKCygh7F8vPpbMEN3Z BcJnU8GV3OPT1qaCJD83UKH9ZmJsGRgjvp6g7BhopTZhKJlpzhvnvV9JuMc474MzCCvt AoEEAJKyW1NxlRN/S4aIwwqWAMD4s8iEogCuE9tMmtevuYBQdpDRYwJk0KXAUH6z5cCS lUuENevEzfOA4c1PY/XOChDGXJenJeZbdZ+bMdfXPz8vLb2Kq2vVCV/ty+wdZGbosGFL cJkg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=XLh7nPd5; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id a12si12988198ejd.417.2020.08.18.08.45.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Aug 2020 08:45:18 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=XLh7nPd5; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 0461C82232; Tue, 18 Aug 2020 17:45:04 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="XLh7nPd5"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 31D54821F1; Tue, 18 Aug 2020 17:44:59 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 04EEE821AF for ; Tue, 18 Aug 2020 17:44:56 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=etienne.carriere@linaro.org Received: by mail-wr1-x42f.google.com with SMTP id r15so8803133wrp.13 for ; Tue, 18 Aug 2020 08:44:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=R78OpiNxqITlOP90Ir31jN3cIvMlK93IuJHKOIFXF/A=; b=XLh7nPd5CgHIKDEAIBt63CeBdc5jUcRJ96YuS4y8b+T62TMgp5ISRPCiwt2/2jfRbC uQqjsYEHRVHG38RIq/AXH1fAZfClQolXrW86+6MXzig1rIWLShrRYpnqXmoyBpktnMzY WfcAGYX/cuiVD9cB6wpqTQ4eKtJGpPPlhNGgxTFSABlswZuA5t+CvMC+NlckvFs8bhIF 2YPTpKDGeJ/C78G1w6ll1YLu+2v7/uf1IOrKKMTdBr2bOeKFn+DGNIgDvTvmUvg1InSk fcl7qfYO65i9BRvnTz3MVN+DeZoMGbrJjBWHpndyX7B6FBc7sf/2hlU8oDSOIqIg4kJw zm+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=R78OpiNxqITlOP90Ir31jN3cIvMlK93IuJHKOIFXF/A=; b=YMckP8Wu6PAN+5j5au1Tl4058HgRoTClu9+uu7y88KE6p9vp6BzAF34Tc2jDiLB5pu jotS/jfpzHcOOBfz08ZsT8zVda2opEjNdltJ3UE99a5NetO6OUNx1f+/McT5s/vMFdhR U7n0YZBtTl1Xoude+5h2M/6NfaIrbhVVqvnQJEQbIKEDC/DdPHpLBwcrnKhK8VyLSmvU iQOqoo9lqim5ceawJEEdeMXygQHL1T11UKYajgvt64WxJem1ICJLCrLmDUIZYJWegRKS 6osegIMo04eBY0XBL8nCjAwx5FElFpRTaTAodu4C9nE6k13PylimA2j4qFt8w3YGZcCu rWWg== X-Gm-Message-State: AOAM532CQBTyK0hoL1vTILbX6r7yXAtK4RH2Lh1gmG3mBmr/bIJ5oHTZ SqctGw6CGWdi8T/s78/Z71t4WWhir7hZz2Nc X-Received: by 2002:adf:f48d:: with SMTP id l13mr20194858wro.43.1597765495172; Tue, 18 Aug 2020 08:44:55 -0700 (PDT) Received: from lmecxl0524.lme.st.com ([2a04:cec0:11d8:1838:f15d:dd00:3cff:c56f]) by smtp.gmail.com with ESMTPSA id h11sm35772645wrb.68.2020.08.18.08.44.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Aug 2020 08:44:54 -0700 (PDT) From: Etienne Carriere To: u-boot@lists.denx.de Cc: Etienne Carriere Subject: [PATCH v2 2/4] dt-bindings: arm: SCMI bindings documentation Date: Tue, 18 Aug 2020 17:41:31 +0200 Message-Id: <20200818154133.22028-2-etienne.carriere@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200818154133.22028-1-etienne.carriere@linaro.org> References: <20200818154133.22028-1-etienne.carriere@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean Dump SCMI DT bindings documentation from Linux kernel source tree v5.8-rc1. Signed-off-by: Etienne Carriere Reviewed-by: Simon Glass --- 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@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 -- 2.17.1 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@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@0 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x200>; + }; + + cpu_scp_hpri: scp-shmem@200 { + compatible = "arm,scmi-shmem"; + reg = <0x200 0x200>; + }; +}; + +mailbox@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@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi_dvfs: protocol@13 { + reg = <0x13>; + #clock-cells = <1>; + }; + + scmi_clk: protocol@14 { + reg = <0x14>; + #clock-cells = <1>; + }; + + scmi_sensors0: protocol@15 { + reg = <0x15>; + #thermal-sensor-cells = <1>; + }; + + scmi_reset: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; +}; + +cpu@0 { + ... + reg = <0 0>; + clocks = <&scmi_dvfs 0>; +}; + +hdlcd@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>; + ... + }; +}; From patchwork Tue Aug 18 15:41:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Etienne Carriere X-Patchwork-Id: 247901 Delivered-To: patch@linaro.org Received: by 2002:a54:3b12:0:0:0:0:0 with SMTP id j18csp3231042ect; Tue, 18 Aug 2020 08:45:40 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyxS5/LfRn0cgHnNPc+MxwlCT35wE3MXbrtQZ2NeaOb4gwiDpgWEwBHyYexnsK3NkO6RbBv X-Received: by 2002:a05:6402:1427:: with SMTP id c7mr21189813edx.245.1597765540778; Tue, 18 Aug 2020 08:45:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597765540; cv=none; d=google.com; s=arc-20160816; b=l4kG/cEgIP4n2OQWH66I8HAEEs+7AAYM5/VK6PHzhZuh9mUmWxzxUHutdDmQtITqU3 YtgmR5gK9bPGdf6d0oIGru6rqJ18/C6g6I3BRIj/EsFGvLXs1PjsbkvNDrLwgzr+h89l PjkXKZPZ7+xXN4F8h6dYfqTxA/+56i5UdsGtXnghEYNZ03NNU1vC6Q8uDsxI94PNMgIT aAFyAwCaotRM6+pwSygmLDYVLm/GqT15+rLLR4gi78wvgUja8i8Z9Nlu1lXy97I6ehHl FiedScG3ZGVLziqO+BaNJ69rr5PmTmY3LMWgm0kpt7VlMYlD/Ius4OBWnCoap7d3odEj sEOA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=VlYNOFMuO/FUMVlfOWT3tYotWQdF6bun2cig5lJ0o7E=; b=NXQnBikLLVIYfghdCHnKUE5BGbw99azj+gG+ocMCCR7fCSVoA/gwUYf7Xhumd7KzJ6 MckvIWEZqSyn+ltBftOGpXA05OTBrwLvRtRcvuS9m7yKxJqtugjGkudEGNhrAFaow/FC CGA9vNWpl1VBXDoVgxa1wa4T2Nfs9IAgB5Ju5N8DtlQPeREIh5XfIEWxAP+REcghWJ7k h6XB8f+IaOr6IsNshbOiIGzROBOnYb/klMAYgBSRKwvWaJBlPHYQkNqopWJmzd++9ezB oDB/YILt04gdNIT15YJ3ZRX956McSVN2MgtVG8V88TBFwLhcdGlpntR9OSoqVwxqYXYM GuBQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BDJIhrmo; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id c12si15422602edn.358.2020.08.18.08.45.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Aug 2020 08:45:40 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BDJIhrmo; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id F39E28223D; Tue, 18 Aug 2020 17:45:11 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="BDJIhrmo"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 28E0882239; Tue, 18 Aug 2020 17:45:04 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wm1-x341.google.com (mail-wm1-x341.google.com [IPv6:2a00:1450:4864:20::341]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 0697B821E0 for ; Tue, 18 Aug 2020 17:44:57 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=etienne.carriere@linaro.org Received: by mail-wm1-x341.google.com with SMTP id d190so16659483wmd.4 for ; Tue, 18 Aug 2020 08:44:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=VlYNOFMuO/FUMVlfOWT3tYotWQdF6bun2cig5lJ0o7E=; b=BDJIhrmoWeNNqMcpoakPHmj8D1kTK2f0hT6rrcJY4klhVBpq5z01qNQU1TFGqH1jaE ZoHoQ/qkSlVehbcSLTCjm/Mn+cdy7pDUOr5gorJmnvNzJTa3yLko95y23ccDJtTmmhbn 5NV5+6OUf1TECRsD7Pzp2LVWQ+hTivkK0sEmClnq/54PmgcU7zee4Vo83KTl6h2rKYrN R97atpLHLftRnMvcYIunhMbmmFsq99bGcrWE84wNUZQ5wfhfkXd05eIisF5wi4PXpywG LKxA3WfxAvC/vsXLcMWx9w5gx/vWA8GA4NxjbIu+wkcsK4DG57wzVLWIZrmR7EjEkyK1 WcwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=VlYNOFMuO/FUMVlfOWT3tYotWQdF6bun2cig5lJ0o7E=; b=roCYqzXui/yrP8tng32COLe1TxublGhjnP3ktU9hxlkGz0PfL0cxA3SK1vFE2xm6gh jLbvoX4IGinUkhTgPizWD7vW3nCx1qa4UgsZCA7Y7YJAnLBF26U+zelwFdcKDzwpjJTk THKCu0XiljOPvWRsgLQHZ0rZZeSLVxCfCH11DoI5BHee0AyVIaPv/txOrnKSk0ZdX/Dx 8eI6GabwHvC0/N/Pg1kzUcqbLylukcqPWHM26Jx696Atvfve3IM1q2VJlRFYaYYOOizR 6Pa+er6AQQc3MoNqBUFGpBQuxs5OU/r0sxPma+CtUrHHb1bM67uoWTmBGJqZzXOK7Kn1 Uu3g== X-Gm-Message-State: AOAM533MYtk4Bce/kh1MKcybijzji1nL4UBVMiK9li5zBuiGV2avM0kH h/W54+0Z7jHz4juN6wayO+Q1qUnQ9ff7l2Es X-Received: by 2002:a7b:cf2f:: with SMTP id m15mr485917wmg.69.1597765496417; Tue, 18 Aug 2020 08:44:56 -0700 (PDT) Received: from lmecxl0524.lme.st.com ([2a04:cec0:11d8:1838:f15d:dd00:3cff:c56f]) by smtp.gmail.com with ESMTPSA id h11sm35772645wrb.68.2020.08.18.08.44.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Aug 2020 08:44:56 -0700 (PDT) From: Etienne Carriere To: u-boot@lists.denx.de Cc: Etienne Carriere , Lukasz Majewski , Simon Glass , Peng Fan , Sudeep Holla Subject: [PATCH v2 3/4] clk: add clock driver for SCMI agents Date: Tue, 18 Aug 2020 17:41:32 +0200 Message-Id: <20200818154133.22028-3-etienne.carriere@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200818154133.22028-1-etienne.carriere@linaro.org> References: <20200818154133.22028-1-etienne.carriere@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean 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 Cc: Lukasz Majewski Cc: Simon Glass Cc: Peng Fan Cc: Sudeep Holla --- 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 | 186 ++++++++++++++++++++++++++++++++++++++++ drivers/firmware/scmi.c | 3 + 4 files changed, 198 insertions(+) create mode 100644 drivers/clk/clk_scmi.c -- 2.17.1 Reviewed-by: Simon Glass 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..6abeb1a4c4 --- /dev/null +++ b/drivers/clk/clk_scmi.c @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019-2020 Linaro Limited + */ +#include +#include +#include +#include +#include + +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; +}; + +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 scmi_msg = { + .protocol_id = SCMI_PROTOCOL_ID_CLOCK, + .message_id = SCMI_CLOCK_CONFIG_SET, + .in_msg = (u8 *)&in, + .in_msg_sz = sizeof(in), + .out_msg = (u8 *)&out, + .out_msg_sz = sizeof(out), + }; + int ret; + + ret = scmi_send_and_process_msg(clk->dev->parent, &scmi_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 scmi_msg = { + .protocol_id = SCMI_PROTOCOL_ID_CLOCK, + .message_id = SCMI_CLOCK_RATE_GET, + .in_msg = (u8 *)&in, + .in_msg_sz = sizeof(in), + .out_msg = (u8 *)&out, + .out_msg_sz = sizeof(out), + }; + int ret; + + ret = scmi_send_and_process_msg(clk->dev->parent, &scmi_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 scmi_msg = { + .protocol_id = SCMI_PROTOCOL_ID_CLOCK, + .message_id = SCMI_CLOCK_RATE_SET, + .in_msg = (u8 *)&in, + .in_msg_sz = sizeof(in), + .out_msg = (u8 *)&out, + .out_msg_sz = sizeof(out), + }; + int ret; + + ret = scmi_send_and_process_msg(clk->dev->parent, &scmi_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.c b/drivers/firmware/scmi.c index 264f3d99c8..cddfa0bbc2 100644 --- a/drivers/firmware/scmi.c +++ b/drivers/firmware/scmi.c @@ -457,6 +457,9 @@ static int scmi_bind(struct udevice *dev) continue; switch (protocol_id) { + case SCMI_PROTOCOL_ID_CLOCK: + drv = DM_GET_DRIVER(scmi_clock); + break; default: dev_info(dev, "Ignore unsupported SCMI protocol %u\n", protocol_id); From patchwork Tue Aug 18 15:41:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Etienne Carriere X-Patchwork-Id: 247900 Delivered-To: patch@linaro.org Received: by 2002:a54:3b12:0:0:0:0:0 with SMTP id j18csp3230922ect; Tue, 18 Aug 2020 08:45:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyC1VgszlR02BOpgw7ayrp/XijNhAhnfyQNidyOjxZrgVj6cWnUdZJNgypTen4ddExc3DbZ X-Received: by 2002:a17:906:7698:: with SMTP id o24mr21517570ejm.182.1597765530663; Tue, 18 Aug 2020 08:45:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597765530; cv=none; d=google.com; s=arc-20160816; b=GAH9GX1czk+X9y8HMIv6u+xiXz9ttFpA1rFm2BVKL1W1Ffu2Wrrrkvbax+OoZpIiwv UdH9NzjVZhHj4SPCKVOi3e6iYorQUmxiz0QX7g0YlhsTpz1YYUJwPJqGGfBSVAXtvmS/ 5qufZAjNGCoSiYlLI6Cdi25V4clUbSzzi6+RW6W2Goh7ukBD9HM78rtyS5NyGRwfjKDJ xt5fRLuBa+z4r9vuAf63Lha/6hhW6LWILENeeqBsy5suGS4MrwIDbtscucsYSTF0dBfX vnSyYqFWPIHqGjsgZwoa0ceQ0xeIlv+ljPxZwuNNGR6fIq0l3RyZ7KO7WNz0ilvbb4OI NUyA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=bJyx/Yo1hHpKSSM28YtiU4jUqHvMw3fY3xHx5cECz5o=; b=uMw8oU59hUnH/EKq8ucQEjDc0bHoC3D4y+lyyIdrMjRNGHE86yERgTOF8vO9BZe9ix X8YfRjjISKc47E8wA0tiYx7VOjtuQjAl9FH418kDpyW/OrZBhjvBtPyyzXwNYS+9rLQ6 n0SCeSdibgU3NMljCAh5lzN+ZVWxUUYjKBRD4VCqCSuAKDa147aaoFh29+tvLRr0d/8V enbydImfcO+NSpIMJa1Tw8IIcF6Iq79m/WdT4GiUu418hVWmrDEyJMqCo0/rJdbNJrqb Xyl8w8Di1fjh5yjI1LXAX7wDu6keRhbzgi/vkpCd0yDIKwxucZACaqgfetGIpjfQ6VXa 8o0A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Mi6a0gRy; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id v14si14239859ejx.388.2020.08.18.08.45.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Aug 2020 08:45:30 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Mi6a0gRy; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id A13DA82252; Tue, 18 Aug 2020 17:45:09 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Mi6a0gRy"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id A80D4821E2; Tue, 18 Aug 2020 17:45:03 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wm1-x342.google.com (mail-wm1-x342.google.com [IPv6:2a00:1450:4864:20::342]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 04CEA821E2 for ; Tue, 18 Aug 2020 17:44:58 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=etienne.carriere@linaro.org Received: by mail-wm1-x342.google.com with SMTP id c19so15627698wmd.1 for ; Tue, 18 Aug 2020 08:44:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=bJyx/Yo1hHpKSSM28YtiU4jUqHvMw3fY3xHx5cECz5o=; b=Mi6a0gRyRWdungzD9H4X7SHpjjgeC9fHAzADkPDHk+/A0fSapHCB/7fIQZGDfGUke+ Y4E4vjro8me6IvpeH/Ms1LHqSJUsWwPHxOCs7z7ulbJpBWm/ag43ldIjGIg++bjfsUoa OLrDD05spKJTDvAI+uXMIJB6nwWEh3jpapT/USR2Vxo50KV0pG0v4EUbcbNCJ0aSGmZS STkFDMIgzaxFx6304+tUlnf9re3PzxR5HImztdlwtRA6YPdLu1c3uN8KA1l0EWYFKfs6 y8N9kHZPPZgYCbreG3JV16Vnxn/DHLT8OA9ssJvVwWt1hSPUMB6oIqEiclk0obJuvFRe XBHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=bJyx/Yo1hHpKSSM28YtiU4jUqHvMw3fY3xHx5cECz5o=; b=kRscJMfTXjumqLX8oYklTpOCX0LcW8XCAPT6uybpEvdJWdXCH305wxWT3DcfJBxjuq aCG4VzdthIjE6YIxt1j5jGTXbsBO3v9G6HmgdbtYZMzHchrnpKbwkGsmjQ1NM4jt3dzh I1iNBJqvcoUpjnuUDYhaFpg+OXsGhMGm0jHs4qQSLePseR/wWA9k8yAqbmBZFQdQgJAX glVjr5xDDf9HtJDDZ6Zg+Jbc7yVK98IxOPLngsiICLhA5kTdL2FO9xHPWoSbkqQaXgF/ SNuD39xLprYR/icTK/vvpi8qw0iIg5iAHgHGoxhx+A3k2XB9vw0YXBwCsccGkHlUH7MA qwOA== X-Gm-Message-State: AOAM531z3Ch0g11uwS3HoqR3wBoo5iKvKO+eq3NMuLRs/FmbMkG3jHKx oVmye2VNKx7IiHY2N6THzs82RQjVI8kgxLTP X-Received: by 2002:a1c:f30f:: with SMTP id q15mr520267wmq.60.1597765497512; Tue, 18 Aug 2020 08:44:57 -0700 (PDT) Received: from lmecxl0524.lme.st.com ([2a04:cec0:11d8:1838:f15d:dd00:3cff:c56f]) by smtp.gmail.com with ESMTPSA id h11sm35772645wrb.68.2020.08.18.08.44.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Aug 2020 08:44:57 -0700 (PDT) From: Etienne Carriere To: u-boot@lists.denx.de Cc: Etienne Carriere , Simon Glass , Peng Fan , Sudeep Holla Subject: [PATCH v2 4/4] reset: add reset controller driver for SCMI agents Date: Tue, 18 Aug 2020 17:41:33 +0200 Message-Id: <20200818154133.22028-4-etienne.carriere@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200818154133.22028-1-etienne.carriere@linaro.org> References: <20200818154133.22028-1-etienne.carriere@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean 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 Cc: Simon Glass Cc: Peng Fan Cc: Sudeep Holla --- 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. --- drivers/firmware/scmi.c | 3 + drivers/reset/Kconfig | 8 +++ drivers/reset/Makefile | 1 + drivers/reset/reset-scmi.c | 143 +++++++++++++++++++++++++++++++++++++ 4 files changed, 155 insertions(+) create mode 100644 drivers/reset/reset-scmi.c -- 2.17.1 Reviewed-by: Simon Glass diff --git a/drivers/firmware/scmi.c b/drivers/firmware/scmi.c index cddfa0bbc2..07a2b0f986 100644 --- a/drivers/firmware/scmi.c +++ b/drivers/firmware/scmi.c @@ -460,6 +460,9 @@ static int scmi_bind(struct udevice *dev) case SCMI_PROTOCOL_ID_CLOCK: drv = DM_GET_DRIVER(scmi_clock); break; + case SCMI_PROTOCOL_ID_RESET_DOMAIN: + drv = DM_GET_DRIVER(scmi_reset_domain); + break; default: dev_info(dev, "Ignore unsupported SCMI protocol %u\n", protocol_id); 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..e8dabc9751 --- /dev/null +++ b/drivers/reset/reset-scmi.c @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019-2020 Linaro Limited + */ +#include +#include +#include +#include +#include +#include + +#define SCMI_RD_NAME_LEN 16 + +#define SCMI_RD_RESET_FLAG_ASSERT BIT(1) +#define SCMI_RD_RESET_FLAG_DEASSERT 0 + +enum scmi_reset_domain_message_id { + SCMI_RESET_DOMAIN_ATTRIBUTES = 0x3, + SCMI_RESET_DOMAIN_RESET = 0x4, +}; + +/** + * 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; +}; + +static int scmi_reset_set_state(struct reset_ctl *rst, int assert_not_deassert) +{ + struct scmi_rd_reset_in in = { + .domain_id = rst->id, + .flags = assert_not_deassert ? SCMI_RD_RESET_FLAG_ASSERT : + SCMI_RD_RESET_FLAG_DEASSERT, + .reset_state = 0, + }; + struct scmi_rd_reset_out out; + struct scmi_msg scmi_msg = { + .protocol_id = SCMI_PROTOCOL_ID_RESET_DOMAIN, + .message_id = SCMI_RESET_DOMAIN_RESET, + .in_msg = (u8 *)&in, + .in_msg_sz = sizeof(in), + .out_msg = (u8 *)&out, + .out_msg_sz = sizeof(out), + }; + int ret; + + ret = scmi_send_and_process_msg(rst->dev->parent, &scmi_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_state(rst, SCMI_RD_RESET_FLAG_ASSERT); +} + +static int scmi_reset_deassert(struct reset_ctl *rst) +{ + return scmi_reset_set_state(rst, SCMI_RD_RESET_FLAG_DEASSERT); +} + +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 scmi_msg = { + .protocol_id = SCMI_PROTOCOL_ID_RESET_DOMAIN, + .message_id = SCMI_RESET_DOMAIN_RESET, + .in_msg = (u8 *)&in, + .in_msg_sz = sizeof(in), + .out_msg = (u8 *)&out, + .out_msg_sz = sizeof(out), + }; + int ret; + + /* + * We don't really care about the attribute, just check + * the reset domain exists. + */ + ret = scmi_send_and_process_msg(rst->dev->parent, &scmi_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, +};