From patchwork Wed Sep 9 16:44:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Etienne Carriere X-Patchwork-Id: 249509 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:dcd:0:0:0:0 with SMTP id l13csp541732ilj; Wed, 9 Sep 2020 09:44:23 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxu7ov/MHlkokJfYcRB8EZEuhpC5dlYCdvZzya7+csSLZxk3fRCzc75Yq1T6Ncl4oQiUwIX X-Received: by 2002:a05:6402:1710:: with SMTP id y16mr5193836edu.197.1599669862845; Wed, 09 Sep 2020 09:44:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599669862; cv=none; d=google.com; s=arc-20160816; b=T8AOKCQgT49bp+JWYbWYWqEAmHuv4lgFzYebSFouKim17Q3OQ0D7jiAAlOerj/bT4m lYI5iX2k2dKzU88bNu5UWnjByY3KnXpgesh7Jv1+KNZLrAHmXXJbIEeArRhqVz9d7JR3 xIBdH0T0rYHJh6t3zOCx75sswe1B+AZ/HpkZWKMSsf/q9LDRMtV3tqRJoF/Qy7r73yfJ yUdSVkP3diXvrQbO6ejZ30NI/uC2VlOu+griW3alrXVwzxo2aEkZaDNeXL8jINdOdQCj mhq4w9vYHVUWepa1uiAqK2g3nmHIM+ezdy2H+apC5rDnLSOj/onrOKqout7pxNzQJjzi Nhkg== 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=AiZlhWfo9XRQnmXmmoQHefW/5t8xfc/EO3BhMZXXo9M=; b=cmsqn+Z0+ZSi+eni8ZvvpjbjoDed4gr85dvCitu5lRtxNeS+FYUzL0e3qrhrWs0KjW ig0v998p/N1VKNOJSS09qolnyip3f7SQjQcpsj3/+mqH/k/Sxjqy9jy9+FpDyMNJcAEN DuP9hRV2Lyw/cX53Lu6CVWSkOUb3bX27p3uDhJRDjnA4YiBdWz4LdTpU2AfXdWb0Vqfr 0MGD1dvYdAjbxvuvtClGzTFo28hNQsMwIaX6/grc2XZ8ESTmDC2sKdY1FcYPPnLAHXgV iQzfXvljY845jBPBHjgsoBjOmTqRAM6g4WPWUpyri2/vNZo3YjrfyPTS10l7E/CO9zsY a8oA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UcXOSjCQ; 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 u17si1866320edr.266.2020.09.09.09.44.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:44:22 -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=UcXOSjCQ; 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 2EBF782249; Wed, 9 Sep 2020 18:44:21 +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="UcXOSjCQ"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 6957C82281; Wed, 9 Sep 2020 18:44:19 +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 79F328158B for ; Wed, 9 Sep 2020 18:44:15 +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 q9so2956624wmj.2 for ; Wed, 09 Sep 2020 09:44:15 -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=AiZlhWfo9XRQnmXmmoQHefW/5t8xfc/EO3BhMZXXo9M=; b=UcXOSjCQ9Z/jNnW/WlQQSllXPEAEmmgzmoLm62cJ6FNW+PPssz332C1DGg7lwOEKzj levQTZ6ditIRLYpZfxlB1TbYC36LuUaSr7HUSYLiVUWL5h+vv1dgnOS10XnKKEav9FUj 9ybZyskvDMsPYYiJK8mkFDllV56ikTnCRbr4IM+Yd+k529aF9W1ewQb2n4i8CvWAA9QS 7l54OKwcrUX2D3C4boBCPWrMsbvCGkU8I7poIxgCWLqSLdtVy4JTM+Gx64Ih9vb3WHCf LMA7kseqIk5A8RjHAdvOyeGILugnibGDz8d3PM3lbopfyBxeDvE7LpvNvhMD9fso/quz fyRA== 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=AiZlhWfo9XRQnmXmmoQHefW/5t8xfc/EO3BhMZXXo9M=; b=CxArXJVDCFVTTeXQY3v6bFMX0Gt79JsSRyM1RX/dAoBP4Ar/6jzS/GE4mOkIWKvO0d x/cb6R71QccsfpDk5zHfEqpm4+eLYnSxbygOhx6og7tCgU+nb7VEAvv3GKr6t07ZTwtQ S64pm/AslXgblR2Z80mQPv3whE9QkO5Nmv3n7fsLkR8vvywq4XBQ6HYfsLgSOAuVvcRH u8U2Ag3cQrdA2gel/3cllQa1QOI3FYFky3oRQvKqPLJ9vWJNLuDFxS7mL/ycABrIZFYg mgookr3+KZ6VLqT3myuW3l1wifR//ChNeWSBzJcizbrCrFY95UDh6Mt1SQDxGdbVoUxK JqjQ== X-Gm-Message-State: AOAM530kD7vZR4yG9zOzpnXym7Y2/txxDjY+Ho1QrSORqWdqOs/N/9wy SFXuy+Tc7vQ+eDksVY8qL5JTnmwuRhUVsTRJL1I= X-Received: by 2002:a1c:2003:: with SMTP id g3mr4112594wmg.99.1599669854678; Wed, 09 Sep 2020 09:44:14 -0700 (PDT) Received: from lmecxl0524.lme.st.com ([2a04:cec0:100d:d03f:c9d0:c7b0:9925:5cde]) by smtp.gmail.com with ESMTPSA id t15sm4468301wmj.15.2020.09.09.09.44.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:44:13 -0700 (PDT) From: Etienne Carriere To: u-boot@lists.denx.de Cc: Simon Glass , Lukasz Majewski , Peng Fan , Sudeep Holla , Etienne Carriere Subject: [PATCH v4 1/8] firmware: add SCMI agent uclass Date: Wed, 9 Sep 2020 18:44:00 +0200 Message-Id: <20200909164407.14327-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 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 Cc: Simon Glass Cc: Peng Fan Cc: Sudeep Holla Reviewed-by: Simon Glass --- Changes in v4: - Remove local helper function dev2agent() used to hide a useless cast. Changes in v3: - Address comments about adding a new uclass and some sandbox test from v2 in https://patchwork.ozlabs.org/project/uboot/list/?series=196253 - New directory drivers/firmware/scmi/. The path mimics Linux kernel source tree for the equivalent driver. - Split scmi.h (patch v2) into scmi_protocols.h, scmi_agent.h and scmi_agent-uclass.h. - Create new uclass UCLASS_SCMI_AGENT. - Introduce a simple sandbox on that agent. Mailbox and smccc agents are moved to specific commits in the series. 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. --- arch/sandbox/dts/test.dts | 16 +++ arch/sandbox/include/asm/scmi_test.h | 43 +++++++ configs/sandbox_defconfig | 2 + drivers/firmware/Kconfig | 2 + drivers/firmware/Makefile | 1 + drivers/firmware/scmi/Kconfig | 17 +++ drivers/firmware/scmi/Makefile | 2 + drivers/firmware/scmi/sandbox-scmi_agent.c | 142 +++++++++++++++++++++ drivers/firmware/scmi/scmi_agent-uclass.c | 107 ++++++++++++++++ include/dm/uclass-id.h | 1 + include/scmi_agent-uclass.h | 24 ++++ include/scmi_agent.h | 68 ++++++++++ include/scmi_protocols.h | 41 ++++++ test/dm/Makefile | 1 + test/dm/scmi.c | 38 ++++++ 15 files changed, 505 insertions(+) create mode 100644 arch/sandbox/include/asm/scmi_test.h create mode 100644 drivers/firmware/scmi/Kconfig create mode 100644 drivers/firmware/scmi/Makefile create mode 100644 drivers/firmware/scmi/sandbox-scmi_agent.c create mode 100644 drivers/firmware/scmi/scmi_agent-uclass.c create mode 100644 include/scmi_agent-uclass.h create mode 100644 include/scmi_agent.h create mode 100644 include/scmi_protocols.h create mode 100644 test/dm/scmi.c -- 2.17.1 diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 9f45c48e4e..dd3b43885e 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -356,6 +356,22 @@ sandbox_firmware: sandbox-firmware { compatible = "sandbox,firmware"; }; + + sandbox-scmi-agent@0 { + compatible = "sandbox,scmi-agent"; + #address-cells = <1>; + #size-cells = <0>; + }; + + sandbox-scmi-agent@1 { + compatible = "sandbox,scmi-agent"; + #address-cells = <1>; + #size-cells = <0>; + + protocol@10 { + reg = <0x10>; + }; + }; }; pinctrl-gpio { diff --git a/arch/sandbox/include/asm/scmi_test.h b/arch/sandbox/include/asm/scmi_test.h new file mode 100644 index 0000000000..a811fe19c3 --- /dev/null +++ b/arch/sandbox/include/asm/scmi_test.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020, Linaro Limited + */ + +#ifndef __SANDBOX_SCMI_TEST_H +#define __SANDBOX_SCMI_TEST_H + +struct udevice; +struct sandbox_scmi_agent; +struct sandbox_scmi_service; + +/** + * struct sandbox_scmi_agent - Simulated SCMI service seen by SCMI agent + * @idx: Identifier for the SCMI agent, its index + */ +struct sandbox_scmi_agent { + uint idx; +}; + +/** + * struct sandbox_scmi_service - Reference to simutaed SCMI agents/services + * @agent: Pointer to SCMI sandbox agent pointers array + * @agent_count: Number of emulated agents exposed in array @agent. + */ +struct sandbox_scmi_service { + struct sandbox_scmi_agent **agent; + size_t agent_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); +#else +static inline struct sandbox_scmi_service *sandbox_scmi_service_ctx(void) +{ + return NULL; +} +#endif /* CONFIG_SCMI_FIRMWARE */ +#endif /* __SANDBOX_SCMI_TEST_H */ diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 6e9f029cc9..2c130c01f0 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -132,6 +132,8 @@ CONFIG_BOARD_SANDBOX=y CONFIG_DMA=y CONFIG_DMA_CHANNELS=y CONFIG_SANDBOX_DMA=y +CONFIG_FIRMWARE=y +CONFIG_SCMI_FIRMWARE=y CONFIG_GPIO_HOG=y CONFIG_DM_GPIO_LOOKUP_LABEL=y CONFIG_PM8916_GPIO=y diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index b70a206355..ef958b3a7a 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -36,3 +36,5 @@ config ZYNQMP_FIRMWARE various platform management services. Say yes to enable ZynqMP firmware interface driver. If in doubt, say N. + +source "drivers/firmware/scmi/Kconfig" diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index a0c250a473..7ce83d72bd 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_$(SPL_)ARM_PSCI_FW) += psci.o obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o obj-$(CONFIG_SANDBOX) += firmware-sandbox.o obj-$(CONFIG_ZYNQMP_FIRMWARE) += firmware-zynqmp.o +obj-$(CONFIG_SCMI_FIRMWARE) += scmi/ diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig new file mode 100644 index 0000000000..57e2ebbe42 --- /dev/null +++ b/drivers/firmware/scmi/Kconfig @@ -0,0 +1,17 @@ +config SCMI_FIRMWARE + bool "Enable SCMI support" + select FIRMWARE + select OF_TRANSLATE + depends on SANDBOX + 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. diff --git a/drivers/firmware/scmi/Makefile b/drivers/firmware/scmi/Makefile new file mode 100644 index 0000000000..336ea1f2a3 --- /dev/null +++ b/drivers/firmware/scmi/Makefile @@ -0,0 +1,2 @@ +obj-y += scmi_agent-uclass.o +obj-$(CONFIG_SANDBOX) += sandbox-scmi_agent.o diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c b/drivers/firmware/scmi/sandbox-scmi_agent.c new file mode 100644 index 0000000000..3179438aab --- /dev/null +++ b/drivers/firmware/scmi/sandbox-scmi_agent.c @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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. + * + * This driver simulates 2 SCMI agents for test purpose. + * + * 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. + */ + +#define SANDBOX_SCMI_AGENT_COUNT 2 + +/* The list saves to simulted end devices references for test purpose */ +struct sandbox_scmi_agent *sandbox_scmi_agent_list[SANDBOX_SCMI_AGENT_COUNT]; + +static struct sandbox_scmi_service sandbox_scmi_service_state = { + .agent = sandbox_scmi_agent_list, + .agent_count = SANDBOX_SCMI_AGENT_COUNT, +}; + +struct sandbox_scmi_service *sandbox_scmi_service_ctx(void) +{ + return &sandbox_scmi_service_state; +} + +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); +}; + +static int sandbox_scmi_test_process_msg(struct udevice *dev, + struct scmi_msg *msg) +{ + switch (msg->protocol_id) { + 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; + return 0; + default: + break; + } + + dev_err(dev, "%s(%s): Unhandled protocol_id %#x/message_id %#x\n", + __func__, dev->name, msg->protocol_id, msg->message_id); + + if (msg->out_msg_sz < sizeof(u32)) + return -EINVAL; + + /* Intentionnaly report unhandled IDs through the SCMI return code */ + *(u32 *)msg->out_msg = SCMI_PROTOCOL_ERROR; + return 0; +} + +static int sandbox_scmi_test_remove(struct udevice *dev) +{ + struct sandbox_scmi_agent *agent = dev_get_priv(dev); + + debug_print_agent_state(dev, "removed"); + + /* We only need to dereference the agent in the context */ + sandbox_scmi_service_ctx()->agent[agent->idx] = NULL; + + return 0; +} + +static int sandbox_scmi_test_probe(struct udevice *dev) +{ + static const char basename[] = "sandbox-scmi-agent@"; + struct sandbox_scmi_agent *agent = dev_get_priv(dev); + const size_t basename_size = sizeof(basename) - 1; + + if (strncmp(basename, dev->name, basename_size)) + return -ENOENT; + + switch (dev->name[basename_size]) { + case '0': + *agent = (struct sandbox_scmi_agent){ + .idx = 0, + }; + break; + case '1': + *agent = (struct sandbox_scmi_agent){ + .idx = 1, + }; + break; + default: + dev_err(dev, "%s(): Unexpected agent ID %s\n", + __func__, dev->name + basename_size); + return -ENOENT; + } + + debug_print_agent_state(dev, "probed"); + + /* Save reference for tests purpose */ + sandbox_scmi_service_ctx()->agent[agent->idx] = agent; + + return 0; +}; + +static const struct udevice_id sandbox_scmi_test_ids[] = { + { .compatible = "sandbox,scmi-agent" }, + { } +}; + +struct scmi_agent_ops sandbox_scmi_test_ops = { + .process_msg = sandbox_scmi_test_process_msg, +}; + +U_BOOT_DRIVER(sandbox_scmi_agent) = { + .name = "sandbox-scmi_agent", + .id = UCLASS_SCMI_AGENT, + .of_match = sandbox_scmi_test_ids, + .priv_auto_alloc_size = sizeof(struct sandbox_scmi_agent), + .probe = sandbox_scmi_test_probe, + .remove = sandbox_scmi_test_remove, + .ops = &sandbox_scmi_test_ops, +}; diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c new file mode 100644 index 0000000000..67a6f907c9 --- /dev/null +++ b/drivers/firmware/scmi/scmi_agent-uclass.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Linaro Limited. + */ + +#include +#include +#include +#include +#include + +#include +#include + +/** + * 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; +}; + +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; +} + +/* + * SCMI agent devices binds devices of various uclasses depeding on + * the FDT description. scmi_bind_protocol() is a generic bind sequence + * called by the uclass at bind stage, that is uclass post_bind. + */ +static int scmi_bind_protocols(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 %#x\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 scmi_agent_ops *transport_dev_ops(struct udevice *dev) +{ + return (const struct scmi_agent_ops *)dev->driver->ops; +} + +int devm_scmi_process_msg(struct udevice *dev, struct scmi_msg *msg) +{ + const struct scmi_agent_ops *ops = transport_dev_ops(dev); + + if (ops->process_msg) + return ops->process_msg(dev, msg); + + return -EPROTONOSUPPORT; +} + +UCLASS_DRIVER(scmi_agent) = { + .id = UCLASS_SCMI_AGENT, + .name = "scmi_agent", + .post_bind = scmi_bind_protocols, +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 4ec5fa6670..88f10c4622 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -94,6 +94,7 @@ enum uclass_id { UCLASS_RESET, /* Reset controller device */ UCLASS_RNG, /* Random Number Generator */ UCLASS_RTC, /* Real time clock device */ + UCLASS_SCMI_AGENT, /* Interface with an SCMI server */ UCLASS_SCSI, /* SCSI device */ UCLASS_SERIAL, /* Serial UART */ UCLASS_SIMPLE_BUS, /* Bus with child devices */ diff --git a/include/scmi_agent-uclass.h b/include/scmi_agent-uclass.h new file mode 100644 index 0000000000..a501d1b482 --- /dev/null +++ b/include/scmi_agent-uclass.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2019-2020 Linaro Limited. + */ +#ifndef _SCMI_AGENT_UCLASS_H +#define _SCMI_AGENT_UCLASS_H + +struct udevice; +struct scmi_msg; + +/** + * struct scmi_transport_ops - The functions that a SCMI transport layer must implement. + */ +struct scmi_agent_ops { + /* + * process_msg - Request transport to get the SCMI message processed + * + * @agent: Agent using the transport + * @msg: SCMI message to be transmitted + */ + int (*process_msg)(struct udevice *dev, struct scmi_msg *msg); +}; + +#endif /* _SCMI_TRANSPORT_UCLASS_H */ diff --git a/include/scmi_agent.h b/include/scmi_agent.h new file mode 100644 index 0000000000..f1be9ff209 --- /dev/null +++ b/include/scmi_agent.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (C) 2019-2020, Linaro Limited + * + * An SCMI agent device represent on communication path from a + * device driver to the remote SCMI server which driver sends + * messages to and receives response messages from. + */ +#ifndef SCMI_AGENT_H +#define SCMI_AGENT_H + +#include + +struct udevice; + +/* + * 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 and response 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; +}; + +/* Helper macro to match a message on input/output array references */ +#define SCMI_MSG_IN(_protocol, _message, _in_array, _out_array) \ + (struct scmi_msg){ \ + .protocol_id = (_protocol), \ + .message_id = (_message), \ + .in_msg = (uint8_t *)&(_in_array), \ + .in_msg_sz = sizeof(_in_array), \ + .out_msg = (uint8_t *)&(_out_array), \ + .out_msg_sz = sizeof(_out_array), \ + } + +/** + * 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 and a negative errno on failure + */ +int devm_scmi_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 */ diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h new file mode 100644 index 0000000000..86a2d109c8 --- /dev/null +++ b/include/scmi_protocols.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (C) 2019-2020, Linaro Limited + */ +#ifndef _SCMI_PROTOCOLS_H +#define _SCMI_PROTOCOLS_H + +#include + +/* + * Subset the SCMI protocols definition + * based on SCMI specification v2.0 (DEN0056B) + * https://developer.arm.com/docs/den0056/b + */ + +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, +}; + +#endif /* _SCMI_PROTOCOLS_H */ diff --git a/test/dm/Makefile b/test/dm/Makefile index 864c8d0b4c..70ba1b6695 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -80,4 +80,5 @@ obj-$(CONFIG_DM_RNG) += rng.o obj-$(CONFIG_CLK_K210_SET_RATE) += k210_pll.o obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o obj-$(CONFIG_RESET_SYSCON) += syscon-reset.o +obj-$(CONFIG_SCMI_FIRMWARE) += scmi.o endif diff --git a/test/dm/scmi.c b/test/dm/scmi.c new file mode 100644 index 0000000000..d8c1e71f12 --- /dev/null +++ b/test/dm/scmi.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020, Linaro Limited + * + * Tests scmi_agent uclass and the SCMI drivers implemented in other + * uclass devices probe when a SCMI server exposes resources. + * + * Note in test.dts the protocol@10 node in agent 1. Protocol 0x10 is not + * implemented in U-Boot SCMI components but the implementation is exepected + * to not complain on unknown protocol IDs, as long as it is not used. Note + * in test.dts tests that SCMI drivers probing does not fail for such an + * unknown SCMI protocol ID. + */ + +#include +#include +#include +#include +#include +#include + +/* + * 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(); + + ut_assertnonnull(scmi_ctx); + ut_asserteq(2, scmi_ctx->agent_count); + ut_assertnull(scmi_ctx->agent[0]); + ut_assertnull(scmi_ctx->agent[1]); + + return 0; +} + +DM_TEST(dm_test_scmi_sandbox_agent, UT_TESTF_SCAN_FDT); From patchwork Wed Sep 9 16:44:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Etienne Carriere X-Patchwork-Id: 249510 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:dcd:0:0:0:0 with SMTP id l13csp541901ilj; Wed, 9 Sep 2020 09:44:35 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw8hGqoRrCdtHbf3XDurprdYFKPInutNMc7U4dshl7sPHs/nNypT13v+3tNZH4lVpfNPEXe X-Received: by 2002:a17:906:edca:: with SMTP id sb10mr4446452ejb.60.1599669875634; Wed, 09 Sep 2020 09:44:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599669875; cv=none; d=google.com; s=arc-20160816; b=DcGyrs6RF1iS9VIefllT/Ea45qgbogH7Bo9jChgHvK63PRRprkoZ6mpScAA7Cua0rS YCAnNrJuhDxCaIo1mbqGXPoIiZzMzrOiirNfxLEJ/6r9le1Mj/pdhEJB1M3dEKqd9wqs IDf2i67Q498K0O4+N5AUEPl7tmLGa8y9wt+WqNgJYlQ06GwPev4ytay2aw4nfy0stYnl qWyAJwIHxamx11Qk/OR+B1MU5QLXDAHaCQBFsBLstbj7PfkF9XfmTmMMat/MrKd79eoE gxXEaPEZ90yCl5qO1SXFCi3Aupoga7sXB1s7G9eoNXWxHk94/TBQc21DhLVogGT+nYua zSjA== 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=A3JAZlnfE5swgX0I9WutqFwbKj1LE8Q4AkFGIhrXe9M=; b=ZEuaFsrKY0ZOTzSBVzpEYA/2D2qfW1eM5mtNZmSfKTMY8zwYwHtMt522ysy439ZMib eK8Fv2nkR8RAWVMhES1/psT7FLKQmiqhUg6pF2chzmFDBukQyMWVl5wyoHtVhUAQkXbF 0ysNFjRbsrJegVYUXdCgPXwzJObDdUG2aNKFfvYBITcrU3jMf5LzzUF8RvyPaHQVzmqX d5Khcjl9IarH4jtF8ORrye/1H6iejH3CsTzn09/pO2efpWwLDmBdVOn65mCT/dvJSAh6 SxPIZufA9xPBhwU71RPzMlCSrEKraOaMe+YQNjMCBGJuSI6EMMcNVatxk5EmaOMnlH3n fGIA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BiIyIYRh; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 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. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id o15si1800343eds.367.2020.09.09.09.44.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:44:35 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BiIyIYRh; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 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 27568822CA; Wed, 9 Sep 2020 18:44:22 +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="BiIyIYRh"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id BC12F82281; Wed, 9 Sep 2020 18:44:19 +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 813A381B79 for ; Wed, 9 Sep 2020 18:44:16 +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 w2so2951655wmi.1 for ; Wed, 09 Sep 2020 09:44:16 -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=A3JAZlnfE5swgX0I9WutqFwbKj1LE8Q4AkFGIhrXe9M=; b=BiIyIYRh9uD13wRsBHxviCgwqNl7QfKkwImdiaBeiRSSr2wtqlvOhltrPe8PU00jTw sY43PybeNA+Ul18qddkfrA7PTqeGinlpzmkc5aylbuaV7X5+D7RKiYlzvpjXCd/TD/M1 kKJuIFbYiw9RkbYS80ftBtpGUTSV0VohfUAIeEFWv6XJL9+uEOLb/8LcxVpAtC0FosD9 kCsA2x+A6kWNNYGB+0GJYtLmi2Et/d2PPRJqnghBnPDbALSo2UlldCMu4l1pxfGCYAcH EfBqn1IyIpMkZx+22eXdByFYMsKrs4jpiu0H9H7MLkl9h0N1EHnEpy+bwURlDKB07GOW +LZA== 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=A3JAZlnfE5swgX0I9WutqFwbKj1LE8Q4AkFGIhrXe9M=; b=fIx+5ZDs0ydKmvZNSQrdaVsRnjcZJMW1nABPVOf25N/ZQjQE3JGgQRPnJ1MC4h9IjH sZvEc4UG1o724hMmtoDGUHYlxREZAIYLu/+TAromrqKR3d937mlH1d6Wc6eTgBA8XCSu HsgkivX8RqWr3Oa7cc1jdwDOtGMx/ThXm8LG5y375jjM5aPlt4dndK4LHiLeG+PQG7vN VM9J3iZxZl0mhyVx1tGAc4gk0gyE4ErILaMW9/UZ6ZJQGX6RL7e2OQGzZWuH9/0i9PMn M/zxm+fQu/0V7X0PBD+e0Hg2Tq+HiGqWrpQuTX+S2yM3r11Xuup2olxN6546QE4fi8tI NNOQ== X-Gm-Message-State: AOAM532mqZqGunDIyY2QliA3TjLEFLj6MFlPqvjTULgKmwOSbuFJgFmx XGn3hBviwfJ4oqY9dQgR9FDU+VqXIV472P8L4to= X-Received: by 2002:a1c:6a11:: with SMTP id f17mr4112360wmc.143.1599669855828; Wed, 09 Sep 2020 09:44:15 -0700 (PDT) Received: from lmecxl0524.lme.st.com ([2a04:cec0:100d:d03f:c9d0:c7b0:9925:5cde]) by smtp.gmail.com with ESMTPSA id t15sm4468301wmj.15.2020.09.09.09.44.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:44:15 -0700 (PDT) From: Etienne Carriere To: u-boot@lists.denx.de Cc: Simon Glass , Lukasz Majewski , Peng Fan , Sudeep Holla , Etienne Carriere Subject: [PATCH v4 2/8] firmware: scmi: mailbox/smt agent device Date: Wed, 9 Sep 2020 18:44:01 +0200 Message-Id: <20200909164407.14327-2-etienne.carriere@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200909164407.14327-1-etienne.carriere@linaro.org> References: <20200909164407.14327-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 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 Cc: Simon Glass Cc: Peng Fan Cc: Sudeep Holla --- 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 -- 2.17.1 Reviewed-by: Simon Glass 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 +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + +/** + * 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 */ From patchwork Wed Sep 9 16:44:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Etienne Carriere X-Patchwork-Id: 249511 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:dcd:0:0:0:0 with SMTP id l13csp542211ilj; Wed, 9 Sep 2020 09:44:57 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzV5E1V973+jUQB4/pF8LD5O/jSJivWIwr7cdelXBrTnHhxHBCbZOEqeULQHhdqfv6HCISu X-Received: by 2002:a17:906:e0c7:: with SMTP id gl7mr4416780ejb.109.1599669897454; Wed, 09 Sep 2020 09:44:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599669897; cv=none; d=google.com; s=arc-20160816; b=rCrSIPM5C3K68na6qsxEsbi5v6EFzxijAwgCxrZQcUojxjC9yH392x04n2ocyePlU9 GVgRc+XHHhikDNZO2bfC/xOHpLSZJcuGk0AgZjftwyv0y+c/GsLr4qPR12/luhTgVvwt 6+ZE9of7zTwKomkGUVDTdtvBj8+FS7Cg1vt0gR2ODltyPBcDiyPPrQzV6hmsbZ3yG8pd f6+nDNQ2wsjuGoydHS+4kiTHS06CkRWsif3+09ApozlItjAtgf4zyro6+DOge7M5RwC6 HflwSTeaYG/ynAcd+DtAdyCkKWEQHjFct65Or4xia7C3fzhYe+QDHOYxnBFSuyirrGfC lsFg== 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=4w1f9prBTyEoA8F3lvTpIKLOYddglqBi1OpeVbnivEA=; b=ivCNbUReYE0QfmkNk2x6haq23rbU44/k7wbC3ur9bL0lWwv4l86T9H87cSR8KoYVsZ GnyoaK8/9ZPe4PUPy6xdXSfCJdNMsnUEo1dsSH9L5y2yAJuAgBJEjlcPv4phYBWrbFk1 HZtNxkTv2AxH1Ojmbm2P8eXK41yOuPj534AJ6gKH03uF5+IbKnYGK8q6yysOAkZcvXTi 81FOlGFeHZWiZ7F5pDlErigVZcozz4F6IhMEwsKbWNsLAh0CA2LLYJ4HpsVU9pRQyNHY 8JWtqBEsAmI2MMidJruhdvEcFZZIgt/Vyqf3v+5DZ573F57uASwoGnHv4F8TeQtnqTqD FZ4Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=n3UzLWtC; 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 c12si1959971edk.238.2020.09.09.09.44.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:44:57 -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=n3UzLWtC; 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 A033982286; Wed, 9 Sep 2020 18:44:25 +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="n3UzLWtC"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 69AFD822D7; Wed, 9 Sep 2020 18:44:22 +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 59E86821ED for ; Wed, 9 Sep 2020 18:44:17 +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 b79so3057552wmb.4 for ; Wed, 09 Sep 2020 09:44:17 -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=4w1f9prBTyEoA8F3lvTpIKLOYddglqBi1OpeVbnivEA=; b=n3UzLWtCHuS+EMfdePMIP3rLsVH5h+TGI6zq94C6iMataSXhaA0fKe1Vmk8kE31/yO 2/Bd1GN5LR6pEx+ETqc+cbFCtADDSK/bP4lAX9R2Jz9L44jjzMfGQwu/QM/5ctuIwHuQ fVAj6igcVQBA7L+B/0noLrttFMYALDWkVlbPMtBBgKvsuh1peyPCXNJ6EZMKkRFyVHg6 +HLyysal6oXGLBhzGgakWgxvQ0JQTQNR0nxBW6sjvQUNvwbagBniFuRcki929IhMf+ey UxgzhRdc7V2SvGTF17zLnT+H1bZ45Op1azkns1hD+M5S0j8kcrZ+O8t3azwsEFE/ljJY I5aw== 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=4w1f9prBTyEoA8F3lvTpIKLOYddglqBi1OpeVbnivEA=; b=b1VdmfuJR8jniz3V+7pnMmYSJK2AnsSpJCJO2xwA52s7HQt8uHEfMEqCccM9+ly7Tc FnbR+uPv2eVeQkWcLcsCIPAPfsESSazDPkxzqE9GN5itzbOO0Vqcjj3suHy4f9L0gnn3 c2BqtB93StV34oujEEGsu4AkjqRIWirxgCe0ZsbZeYV8os+t4ZQBuY0pRzlXzADG6Vs2 HhUpv+GlLVt2WgK8D+KMzkvAeOJWQ7ee2JJIISBj0FtdcKgZsi11M0du1mUitI9bfGJA rSWe9MEqbtWxNBBfNVbvWTs2ZePpfVLA8cJY/teBD0P2ebylLbLutjNNqx4kUJBxOfJ+ IW1w== X-Gm-Message-State: AOAM533sGUeR8KJby++o6KbZMXE1afYw/6NAuWCvDKonmaWAo3fsrQRB FCKaCebdR9UyeGQ+H2lcFnbYNGYyIk7Bdt+HM80= X-Received: by 2002:a1c:a784:: with SMTP id q126mr4265262wme.38.1599669856844; Wed, 09 Sep 2020 09:44:16 -0700 (PDT) Received: from lmecxl0524.lme.st.com ([2a04:cec0:100d:d03f:c9d0:c7b0:9925:5cde]) by smtp.gmail.com with ESMTPSA id t15sm4468301wmj.15.2020.09.09.09.44.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:44:16 -0700 (PDT) From: Etienne Carriere To: u-boot@lists.denx.de Cc: Simon Glass , Lukasz Majewski , Peng Fan , Sudeep Holla , Etienne Carriere Subject: [PATCH v4 3/8] firmware: scmi: support Arm SMCCC transport Date: Wed, 9 Sep 2020 18:44:02 +0200 Message-Id: <20200909164407.14327-3-etienne.carriere@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200909164407.14327-1-etienne.carriere@linaro.org> References: <20200909164407.14327-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 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 Cc: Simon Glass Cc: Peng Fan Cc: Sudeep Holla --- 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 -- 2.17.1 Reviewed-by: Simon Glass 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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, +}; From patchwork Wed Sep 9 16:44:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Etienne Carriere X-Patchwork-Id: 249513 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:dcd:0:0:0:0 with SMTP id l13csp542411ilj; Wed, 9 Sep 2020 09:45:12 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxytsH2ks239CXfgOEZyVAyMflogVBeazieO+utk6Il748nso/d23iIbHyDVVsQdXL7oNj8 X-Received: by 2002:a17:906:4b18:: with SMTP id y24mr4395732eju.471.1599669912323; Wed, 09 Sep 2020 09:45:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599669912; cv=none; d=google.com; s=arc-20160816; b=mBNu58fwdNa858XDAye5sfwvcKMN8z46oi0qAjt7gc4fHqLry6oA4JlpNXJvPOk4Ga Ln5iLZTs12WyidC1JfPNRPpdat3Pu4ea2DvPn7aoCAmh6nWAonSZCu38SOgyu8OP1vvZ 8LCsUV1Zmy941otXd/OeR/XeufygAJSiFD/QIc9ydTfvWNCossrvn7eDa+8j9wuF5swl WPcEcD7hUVbfGcPrgDzsJ7XLI1ZV9MrHZJfbLC/tvGPBkB3BjtRpYYw4VGij4CPvNNkH 4/OiHWbau2d3pSuAeEsy3TZSdH2kYtFLha+cYeObg0f/ie/2+MKrGTQlDuWfsRhssUSr 5iAQ== 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=4QaTeDK539TJolZJjlONUQZkrTnKWtU3mPxd64RPuM4=; b=UC18zRIcYa5F/BqDENk20Ic1Ngr1N9eH+wCGd0LI7u9BpJ+GTDBiEZ4hsVn+axCFFD GOSwSDm1OC5HSUT0ZqXnCXnyQUZmd9ZL6Cy3XN50K7BHzl2tafQkFom+l4OBKoVekKi6 Q4j3Oh7OUulNnchIycbtkyEaw5NlZOmVNC9V9WkvJtITB1CwbxhkkZyLFeWIjWMWqiZj 5NPN8k/f14SJndUK5DDp0xxCa9KoyTAjFD5uXXMUXgvKvnHGy86Mz2H/KgHJ/WiJwFWY lEX+fVn3u8imMkWaTtz4Gm0fNE/HM4WI0d3G+CGkvQFyr9qmZKK0LPKtcqZ75VQfK67o D0Tw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=fMs9vEgr; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 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. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id b43si2034521edf.15.2020.09.09.09.45.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:45:12 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=fMs9vEgr; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 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 7608B822F5; Wed, 9 Sep 2020 18:44:26 +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="fMs9vEgr"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 9F51B8221F; Wed, 9 Sep 2020 18:44:22 +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-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) (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 8A95B8221F for ; Wed, 9 Sep 2020 18:44:18 +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-x32a.google.com with SMTP id z9so3070631wmk.1 for ; Wed, 09 Sep 2020 09:44:18 -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=4QaTeDK539TJolZJjlONUQZkrTnKWtU3mPxd64RPuM4=; b=fMs9vEgrlb/nMhZ0Z0XaRxFDZOhLHlFuOgnAEFc8FNaOf+9EVN5Rxr4Q8EK/aDv9mY oimzyereGm/xgFRr/PuP+r8CQgQiMUZSky/8EqeLKoeWevBLC+dVF5b379SI2TtHGIyQ DIMZeEXIf1hv0GnLmYTNqgp+8Uo3r96L17azSfbgaj4Grww7+kfcW6fDpT5OqDjAE76n l6PYHvPh8yD0IfN3KdH4NSmJU5vuUuTRAN0fSDyjqlAeJQdB8OUlbzcs2IRd9Q8KsQiW W12aQud1b8rflz5fLmDGYjbkL6XPLVi8b8vMmpbl/x+lS+cA5yUT7A4K8ZOUbn48K9nu 2fpQ== 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=4QaTeDK539TJolZJjlONUQZkrTnKWtU3mPxd64RPuM4=; b=iNW7cGYBO1ka8WzLCgoOxXh3kOesdaPPyZMiT3hKXlgXSZEA56t5+imk+64g6TM83V cJHGpuzJ2zwtNCFCU8UKP5VpyCxUkjJOoeTMOlAmJz/QIbjLGcbp+mv/oD1OkUC5LwCP 5cl0D+DFeOjk4i6H/QUB7BpD6zavO2vXeCeSmkxHHg5IZIPZrIxDniKXrfg9A6XscWnv swQVNKOxYX5msjNf6wYI3BPuGXc+YeRvRqCCRUghhKPBzIIEKHiflslfrDg/9DmvLxpk zHjTY07RYgJVMYPXN3X401/JzQM+GXOYM8B2hbEIeiWrP9hXrUVo+7oBgLTHwXuZcwir R4lA== X-Gm-Message-State: AOAM533IbeHtyRQc5cliZTzgLwzCvHVUg9ozDaXtoL6S+War4X08ufIC hwhECWEqkRO3myLj1hz45hdLWziwd0rKCYKORSE= X-Received: by 2002:a7b:ce96:: with SMTP id q22mr4109780wmj.132.1599669857848; Wed, 09 Sep 2020 09:44:17 -0700 (PDT) Received: from lmecxl0524.lme.st.com ([2a04:cec0:100d:d03f:c9d0:c7b0:9925:5cde]) by smtp.gmail.com with ESMTPSA id t15sm4468301wmj.15.2020.09.09.09.44.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:44:17 -0700 (PDT) From: Etienne Carriere To: u-boot@lists.denx.de Cc: Simon Glass , Lukasz Majewski , Peng Fan , Sudeep Holla , Etienne Carriere Subject: [PATCH v4 4/8] dt-bindings: arm: SCMI bindings documentation Date: Wed, 9 Sep 2020 18:44:03 +0200 Message-Id: <20200909164407.14327-4-etienne.carriere@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200909164407.14327-1-etienne.carriere@linaro.org> References: <20200909164407.14327-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 --- 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@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 Reviewed-by: Simon Glass 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 Wed Sep 9 16:44:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Etienne Carriere X-Patchwork-Id: 249514 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:dcd:0:0:0:0 with SMTP id l13csp542576ilj; Wed, 9 Sep 2020 09:45:24 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwXfzl4B06xHubHUXqkNOpi13kT91ssSuyD0qmTAS5uHuKMe7yrG0f9p8ukCj2zPcdgJTPB X-Received: by 2002:a17:906:9443:: with SMTP id z3mr4835768ejx.156.1599669924176; Wed, 09 Sep 2020 09:45:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599669924; cv=none; d=google.com; s=arc-20160816; b=OdugFnxvhRVYv9k11l3pW7/citd6Njvkx9XkqjoVtaWXgwhrZA7nMV6woH+X0WzFMR uV5Sa25iV9yjOdHUM//hppc8vG4E/QjjPmwDfW5iMjIX/aVFnjnSxcLb7Gr2/LIgLE+c 64U8v8FUzO2xXqmh4wQvSF77rpaY46/UNU5MeUWtUkQLXPS2XdOXHPmqC4bvm6ypyVoc 6TnnrgvfYfhiGk594g7SwNFJWCNf7VYAYZHpwZEA4mVumlx3Nxpfki0oMHXT7FgSZJ59 e/JDT/38akF/98InlE8Fyp+tcehOBcI4dNaWvJtjrr2hbIr9jPJZFrGGmHKm2EEm6ihW 5zcA== 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=coIhin5cN8preO2c8Tju37x4D0KZxOR6Yomwk2BwU+U=; b=Gyx3XxE96KucTpv4e0FzvVE04elJMqZ8c9ow5StzHA/yptaSdxueMNlxKBmS/oztjy BE8BMf/TKJwDjaFsr4fqNEup9b9G37AIKEg3aH56nqZzqg9F9Subo8QbVkxCGEjq6Tno WAj9ZYphS/+pX9bZLUVPw/tfj5ffE/by23AcsGraR7eMG+k0hDND9bAVsgVKaSErtcP5 vDY7VTn4qXKPKDAQzHgTGCaZWVRqrRRCUR3EeOf3JmMn/cAEX6afUj/4IA5hPeb/oxvA kxQ4FkkDqWDCp/o1sOnls6KYXGZB/i02arCoESLcDG6d0tGx9J7uCOzU6LDpIrgsnQyH Ah4A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="feM/+2F1"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 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. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id la18si1768004ejb.526.2020.09.09.09.45.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:45:24 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="feM/+2F1"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 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 326A3822FD; Wed, 9 Sep 2020 18:44:27 +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="feM/+2F1"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id C7052822D1; Wed, 9 Sep 2020 18:44:23 +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 7A6BF8158B for ; Wed, 9 Sep 2020 18:44:19 +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 e17so2954308wme.0 for ; Wed, 09 Sep 2020 09:44:19 -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=coIhin5cN8preO2c8Tju37x4D0KZxOR6Yomwk2BwU+U=; b=feM/+2F1CsHbgpmWqykwohKhR8fOe1hoGCzVkBH1yXD5GWLmg+qwVKiJ+UzL7TWrQ6 dNe0nO/O2A/1UKMtfrIBOPPz9XwFLIfZNIEdVyOEQT7+8uP6vSv0o6erom6BWFVMRk5Q a6qGd+ADI+BtXkNyxmOUGvV54dW0qhruXoWrhl5qSphAPePiNClrrGPTxblBq3HokEYl gwwRgCROq6Nv2QMksV/MeTHMSlnMGBEjay9PrgXlcRHBfTGzdWoaPeon7yFdtohmytIr 8l716yidoV9h5s07nRXRQyakJGSdTsEu8RoQDmIITn259HJsn8No8+YwNok3ahBT1zov oEhw== 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=coIhin5cN8preO2c8Tju37x4D0KZxOR6Yomwk2BwU+U=; b=cxd41VWAaGa9CdYVwq8wvodYIDAoppnEHk2h43X55HHS7RCqw4bfAPagR3E55Tg1Dk I0zyp2QZ9973z3H2qSZgBtvhJH30YA+cG2EwqDcY76BbBRTR5K52Yi7nAZdFzkIuER6l S7/UCiMzqqCK6sgH2zygMhB+ZRwSgVq3cDNfD841eeMq5BufnrU9La7WeoKhyhtZAOdh CEJ3T5kIRXUy6DNlCt6TG9Ewh6nQdXNfqQfmwUfWhJKNhes8LgLjCYzTYkjwbUXAq+pA khqfeAiPr+31Ae4GclIMlRhQUjk+Cg/x2qC5dTuSnV3mQlM29zpgi/Vf+h4+i5P+8zn7 WfNA== X-Gm-Message-State: AOAM5326T/Ph8IUmT0otVqzjry2Xqd5CxqDkIkSWMtWNOYocjJKW5kiW nkrUP49t/ro3n2KnV0obEdTk/MpCmjmCeBjZmlc= X-Received: by 2002:a7b:cb47:: with SMTP id v7mr4666619wmj.129.1599669858905; Wed, 09 Sep 2020 09:44:18 -0700 (PDT) Received: from lmecxl0524.lme.st.com ([2a04:cec0:100d:d03f:c9d0:c7b0:9925:5cde]) by smtp.gmail.com with ESMTPSA id t15sm4468301wmj.15.2020.09.09.09.44.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:44:18 -0700 (PDT) From: Etienne Carriere To: u-boot@lists.denx.de Cc: Simon Glass , Lukasz Majewski , Peng Fan , Sudeep Holla , Etienne Carriere Subject: [PATCH v4 5/8] clk: add clock driver for SCMI agents Date: Wed, 9 Sep 2020 18:44:04 +0200 Message-Id: <20200909164407.14327-5-etienne.carriere@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200909164407.14327-1-etienne.carriere@linaro.org> References: <20200909164407.14327-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 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 -- 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..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 +#include +#include +#include +#include +#include + +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 +#include /* * 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 */ From patchwork Wed Sep 9 16:44:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Etienne Carriere X-Patchwork-Id: 249515 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:dcd:0:0:0:0 with SMTP id l13csp542742ilj; Wed, 9 Sep 2020 09:45:35 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwCMd1tlYqHaZiQgAxa384gAe9mvuo/OPJMzeAADJOC4KtL1xDmJUxc7G0Jd3gXB87AtIm0 X-Received: by 2002:a17:906:72d2:: with SMTP id m18mr4446055ejl.220.1599669935767; Wed, 09 Sep 2020 09:45:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599669935; cv=none; d=google.com; s=arc-20160816; b=D952sXBToRFziv16NTeDzScjsNHRcxIzZaeiOvXVSMaBCjYITE5laVgLgzWfu9hDpv +SvaILVwQxG9V9kcrKRcuT05yqJlEYUrtJlbHo5oG6mTtvy3snmpUZldGqgSWPx8sYm3 5W3IkplCVLMrxw6GKTh0h9WwEQKfJntle22Vhqat0edl1PmDHQNBYtKHh39HalM5F1Qj kGWYQCKXI7iKhzQkb5Q02c0q58NyMbc8ihLt/feiPg/a5UNm97sFbIo06HZPgUntpLmR FC0W3Tv2gSUOoUIh9elR+oJ2I2F7sVljk26K9Htxs9xIxADByQNTliiSCvAzhxyeyIUH QSKg== 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=hf9bvnO2AOEa5TUqBNhednbomgYVXY76JjFO2ZXkHJE=; b=DzIQISPmpLF4Oky5jq+WukRfypt8jpc43id0/g1bwfsHUZqWPb+npEiKmmXUpC3YKS Vd07p/D72pB27BP53DSjYbbc5fwYQ8ROrUBdufJXcTDZE84ITEOlwB9tc9ObZnmPhUB7 AvQshLautD5iCGnLFkw5sXV1n2k8Bs8Xsl9dQraeREa/sFtQZRK3szqj9NU9JqkSAJUo +3f/mcdB5MB2LK8uVRrOnFKrMWJ360KO2r20Lc93NnWXcJ7YASf6KN5eMHsudlqe1Qfg gB2GHMDSGVGJGzqriQVTsi7zvc/AjfpkL5yz/PLfWuTy08ZnTgtP9x/fyY9QR3Y4BRVZ 0IKw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="TT1n8/DH"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 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. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id h24si1847986edv.391.2020.09.09.09.45.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:45:35 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="TT1n8/DH"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 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 075CC822EC; Wed, 9 Sep 2020 18:44:29 +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="TT1n8/DH"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 20B8A822E1; Wed, 9 Sep 2020 18:44:25 +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-x441.google.com (mail-wr1-x441.google.com [IPv6:2a00:1450:4864:20::441]) (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 A83CE81B79 for ; Wed, 9 Sep 2020 18:44:20 +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-x441.google.com with SMTP id w5so3681094wrp.8 for ; Wed, 09 Sep 2020 09:44:20 -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=hf9bvnO2AOEa5TUqBNhednbomgYVXY76JjFO2ZXkHJE=; b=TT1n8/DH14q7m4FiO+02cWfZhrCMI9k/B8LV5uHUXmJLfYOxsc8d+Lgc/0zZqUbqUF UFrNAHRnrX+u8pz4i5R/1r1UqK4iir7nA19UWgGjhvRnwpliab3a1+NJCvrBwX6QeLif dt9QFgNKHHorNpLS+a8dZmG4NZCf5A9QYI+C0wA3vFBL3wBJny75nA4tfsCCSvXxKu9B 89+brW++a6QYbRRZv2tPxtKWiT9W3DAVHuxm39eeWn8dd0lv5j0cjxviRgZTX0N+SB98 kZ2haJcuRp//L7G+th/UPJ1rkHJCgD9gyB9itwAz4v545/NQQtWcgtTLYzFH0/krFKLz 036g== 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=hf9bvnO2AOEa5TUqBNhednbomgYVXY76JjFO2ZXkHJE=; b=NBa6CTeY/3iVceACDYnjE+7Go5zuSVJVxskQHx25NyvmFPnW5jX4KNw+wfuYD6PdYs 8rmryurNTUGNKd+Lwy8Lji4MqKFwQg0KgznjJVZ5aBEmPYhxzUjux/9qnVel7Ww2DmYp 2FsHxRwWHvae4Ppz49SswTeIcowhmi7jw61UOXBoAwjxvcwAt7RW5O4gEm+v2A9FO4FB jmSYPPGDjyd5RmGNs/70udUs9dgQiV4pOwYyJl6caVUq5gbkJqyTOjpFN3wDeQH4zifI vaokFwlF5caDc7wXSsp3tzT0TIiHYfxa4zZSgDy4mUuOFoa1yCFy8q4c5UCHRnTUjXsA jgWw== X-Gm-Message-State: AOAM533PPd/KBdTOpHegnAUih9eB4H3s4oM3bzvZqCu0mc5UjztGliwG phVZpaBdSGE6QixRdDVX39dRxi0Oi6qs0A0XvYk= X-Received: by 2002:adf:fd8d:: with SMTP id d13mr5052085wrr.104.1599669859969; Wed, 09 Sep 2020 09:44:19 -0700 (PDT) Received: from lmecxl0524.lme.st.com ([2a04:cec0:100d:d03f:c9d0:c7b0:9925:5cde]) by smtp.gmail.com with ESMTPSA id t15sm4468301wmj.15.2020.09.09.09.44.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:44:19 -0700 (PDT) From: Etienne Carriere To: u-boot@lists.denx.de Cc: Simon Glass , Lukasz Majewski , Peng Fan , Sudeep Holla , Etienne Carriere Subject: [PATCH v4 6/8] firmware: scmi: sandbox test for SCMI clocks Date: Wed, 9 Sep 2020 18:44:05 +0200 Message-Id: <20200909164407.14327-6-etienne.carriere@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200909164407.14327-1-etienne.carriere@linaro.org> References: <20200909164407.14327-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 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 Cc: Simon Glass Cc: Peng Fan Cc: Sudeep Holla --- 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 -- 2.17.1 Reviewed-by: Simon Glass 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@14 { + reg = <0x14>; + #clock-cells = <1>; + }; }; sandbox-scmi-agent@1 { @@ -368,6 +373,11 @@ #address-cells = <1>; #size-cells = <0>; + clk_scmi1: protocol@14 { + reg = <0x14>; + #clock-cells = <1>; + }; + protocol@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@0" in test.dts. + * + * Agent #1 simulates 1 clock. + * See IDs in scmi1_clk[] and "sandbox-scmi-agent@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 +#include +#include +#include +#include +#include +#include + +/* + * 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 +#include #include #include #include #include +#include #include +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); From patchwork Wed Sep 9 16:44:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Etienne Carriere X-Patchwork-Id: 249516 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:dcd:0:0:0:0 with SMTP id l13csp542872ilj; Wed, 9 Sep 2020 09:45:48 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwNqToaZsgfbvpGsTdYck5CoHEFHqvSpylcpWZ4DdoQKvvkxetPXEjc0FuZEE6Nt8qZAbaw X-Received: by 2002:a17:906:fccb:: with SMTP id qx11mr4665879ejb.429.1599669948685; Wed, 09 Sep 2020 09:45:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599669948; cv=none; d=google.com; s=arc-20160816; b=r9fVvM3BzbATnNrlwVleIZwVkRLls4G5tmykxZpBWiv1ZyMcR2PxB/di/FHA3vbOFX /xmZg+acfzvyF4WQOCFoD3bX8O4HAl9vRT/cKygUNohuuotkhY/gQo0iYIZ0ZcALXett AC1PIfuM26w9G1MqxW68pQv6BhhfYP3Czr4ZOM4KLlYa+BbMPryL9qHn9uKEl1mcoZHR UkMS6Bfz0j1u2ndMm+L7or+qLB4HBDvDRAgGk9F5Ct2QBlzTZcwuViXPBgQtZgxNMnx/ FH9fZtab9MleeqyKv6XNyEmj6yVY+7yy3YcRc4Xs0nw70/BwNkGov9yVKE2m7XA1hk/+ 6kyQ== 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=hvG9KywC9jPjn/LQNy2rkL7YAy9Jd3I6VZldARDbyds=; b=ksbXo66BBcnkuKGcwMAnVdyApb5d8yJlGuVIebbAQF7L8KRS055251hTvAXiO2XkbR TFc3/8jfRsQ3/NwbzgZdg8S3jwlYLeJP7bdImxrfP1inqVehVK6q+WiJMR+9xCKFnN2v gf8+IkuD24TzznMZqnqP06Go1tEav6mh9ZTwWzd7e9mDCnpU9Bi/7BvtrcECxUkhNlgF GX7JeyPgRarp3hZGXwk2GrNWVnKtGGPtuGe1Ui6u8EVGLgyHY+a/p5dZPfN07QAebM53 S+WO9hvLhdSEFHxdxwcmlQSNaRRRqg/uSYkW01+P/yK6NM1YCTESTNMx4a1vGBsX0Myn 3arA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=N+p75nEd; 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 h9si1947403edv.170.2020.09.09.09.45.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:45:48 -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=N+p75nEd; 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 C7BA982314; Wed, 9 Sep 2020 18:44:29 +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="N+p75nEd"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 8DAF9822ED; Wed, 9 Sep 2020 18:44:25 +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-x343.google.com (mail-wm1-x343.google.com [IPv6:2a00:1450:4864:20::343]) (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 89F8E82286 for ; Wed, 9 Sep 2020 18:44:21 +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-x343.google.com with SMTP id l9so3062263wme.3 for ; Wed, 09 Sep 2020 09:44:21 -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=hvG9KywC9jPjn/LQNy2rkL7YAy9Jd3I6VZldARDbyds=; b=N+p75nEd8wCdqV/XsQp0e/tQJpz6nW7Mq61Tv8wspDb/JCW+Ulg41tij6U40VblCJ7 B0q8ZDT/M49JPhMP1djuEmiTb4Pb6u34So6F7oGpOzrchRUgehQWxpOyLiRJOOAmji7e 7d5d1Q6a1vMXp0egq1DMDdoRREJTW+v4c9SmXoiS7YowOVgHOxWSQ5R5JYdaMS1nSpUt LfAY/8hEZlcnV2TVRyFbHuGDMfXM95yxKbFcYoahNnmbwTpkBgbwb4Puj3J582j0CDyn HFBlvRCCJnWtsnfY0HSK8wW5nw1Ae9Fzuk1DgeFckzsnu4vJQ6onUJf/hyoE0Oub7hE8 LQqQ== 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=hvG9KywC9jPjn/LQNy2rkL7YAy9Jd3I6VZldARDbyds=; b=p1yWw+eyj2BzZlEWvLUoW+7aY3Uon8T2MgU9CV/ZhAYkV4RM/GKUS3Q46IgD+idUr5 KdVECebuiClQ3naDocVRjH5KbEEy4jhAsTA5wHVuyCUzWGm8iP0xyPQgLa8hTPHEN9Up KRv5ZvLMuxgstyCjyp+lj1Y5QWjlwhODTnZVC2yQDJWr5t2i1bFkN2BLl2FP+dFALwHS XsAbI0FxRIJci9ietS8kXycmMiM/oKO5lHMMzIT9p+D6Kyl8lEsqmsiLIHnPvo73un1N MmEUF+WqRoxNWk1qhDo1WX09HwdOvnnuZTUwmipeea9AwKHir3u1i6KaIHYFPhupU7mK ofQQ== X-Gm-Message-State: AOAM533vwZNe+0Tz+OG+8478ZFPbpNGn4HSOx7R7ADLyaaS1sMs78Mgf bjT3IEbf9dn2GHX2Pksoa9J4BUWjBJkDUwCT+w0= X-Received: by 2002:a1c:7911:: with SMTP id l17mr4311312wme.179.1599669861017; Wed, 09 Sep 2020 09:44:21 -0700 (PDT) Received: from lmecxl0524.lme.st.com ([2a04:cec0:100d:d03f:c9d0:c7b0:9925:5cde]) by smtp.gmail.com with ESMTPSA id t15sm4468301wmj.15.2020.09.09.09.44.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:44:20 -0700 (PDT) From: Etienne Carriere To: u-boot@lists.denx.de Cc: Simon Glass , Lukasz Majewski , Peng Fan , Sudeep Holla , Etienne Carriere Subject: [PATCH v4 7/8] reset: add reset controller driver for SCMI agents Date: Wed, 9 Sep 2020 18:44:06 +0200 Message-Id: <20200909164407.14327-7-etienne.carriere@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200909164407.14327-1-etienne.carriere@linaro.org> References: <20200909164407.14327-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 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 -- 2.17.1 Reviewed-by: Simon Glass 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 +#include +#include +#include +#include +#include +#include + +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 */ From patchwork Wed Sep 9 16:44:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Etienne Carriere X-Patchwork-Id: 249517 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:dcd:0:0:0:0 with SMTP id l13csp543005ilj; Wed, 9 Sep 2020 09:46:00 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxeEmARC2PtQGr9AZyJ94PlM0rk58jdv6rxDu8j93G1XwozQQs9cND8EKTjOpW5nMaBjFZu X-Received: by 2002:a05:6402:b68:: with SMTP id cb8mr5096940edb.350.1599669960767; Wed, 09 Sep 2020 09:46:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599669960; cv=none; d=google.com; s=arc-20160816; b=Oom8Rg5SHvDJ/TMAo3tAieSGPbjUMW64BSxi1GOc3Y9HQoKE5Cw7TbXjoC6YP5ovT8 GcpTHTZ7/LNWZthqal2N0FKaqNH7mnOaRLgolksIaeLCrUjR/UeyVU0jfv+0j7UvoCB0 Q9jOLAD12+KF4HXYuMyob6oOFSd3GAoAR/POUREFXRYjIEhiP7Ii55BUBHF05koE+Nbw Xbzilxjpe2qveMDl3kXNvkzSeJOrxBd6V1CsqmoVbzh2OVCIdPKe++V2H7/UadN23mZG oIVTmiCqYpS4stwApvrIWXTxcrMJ927nBCi5bVPjI7f67dmvUzbhXog3yiuYJ6uRa7NH OJdg== 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=oaBHCksdwRD5zbn+GHUVWqWVgmDuRCtLypLhWCyPsFE=; b=tES89DDLcvm+XAwo1A9Kq3r+pXmazXFkgCUJKAt/s/wv34IgSyiT+g0xhRr5d0ygqz ff5kw7et1gz7uWnT4P/e1IvmdKG9n0C3Zk/ptbXBNNifpplrmeZNjE3aVhvBSdyCgCCX C/ofO+s3AlFfnOtXFOWlsuOjFO4wAUfqsK/pCHJsYmPtAPfjOjn/crn2DX5PR/0yl6WJ ChvQzQ3Ft8/7a17jUjREsIwI3XbhsGj3hgmudCfZnEeEC5sijuKxgTcl7fyX2lgnDza6 KbbnAh5gB3RJO8Ry328pNw16Js0DLRDpyCUxqEuFLlY08UAUxfDhY1K33RO6RA60o0gZ MoEQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=tCnTJvj3; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 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. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id g19si1968617ejz.608.2020.09.09.09.46.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:46:00 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=tCnTJvj3; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 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 E10EE8231A; Wed, 9 Sep 2020 18:44:30 +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="tCnTJvj3"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D071C822E1; Wed, 9 Sep 2020 18:44:25 +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-x444.google.com (mail-wr1-x444.google.com [IPv6:2a00:1450:4864:20::444]) (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 9B7E1822CE for ; Wed, 9 Sep 2020 18:44:22 +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-x444.google.com with SMTP id m6so3730198wrn.0 for ; Wed, 09 Sep 2020 09:44:22 -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=oaBHCksdwRD5zbn+GHUVWqWVgmDuRCtLypLhWCyPsFE=; b=tCnTJvj3mwdSsp0j+AVrws+GaKkCTwJhM2CeRjPzGITD6UO2Dv8IPm/H0IhFLKmyyk KxFCrVMWg9gWVXxmqkpRFLxH0zIvEcm079m4V5hCziUeRloTNvup94LdGHSS04ws0f79 nZLlNOwcjPMUUk3dcvliMFT/CZC+LdtXiFkYXcdSbXg1QGrRdv+uXgOt2tWWgFxfnF+c AoW0NlkD/1qdOloySM1b5MH8R88WUZxOb0tpRlEq4oHGdT8wcsNHD5r6FEtdkY8RUSAC +hP6DrZ8S9qDC3iFkCe2gb84pSKJjivEC25MhgSxetf7Kil/CEHY7no2a0yKB9nO7m4z 5CLA== 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=oaBHCksdwRD5zbn+GHUVWqWVgmDuRCtLypLhWCyPsFE=; b=EflQ2cBR/5WL5j7vaeaKywIptKvMwJ84PvRgeX6yn6XAk59ONd8jaH9YEAjHmWz6Ag 5t5D1e/araYUZqdojvobmVnxiF61JjlLpOSy08LjcSHnHRXmOmXTbmJPqcm0zdDwEDRM RrYbDNmxXFTMwZ3QgicwlRsar9TzwRZRSvYhUS2KnKd8gye7AREbFRrxgzEONgX+ta2r AZpI8yDnKEtPSJvaPZvdI8n1mD3HuUextAo2PQX8y5LsPxJgP2oxY70LUQcAJ3jgk0Fx acuMueXxEpBhYztaQVuYtG8Zl6/PAZvOclPcZCiiuQnGZFw3LgOSrtoyZX05qORKL80P NlfQ== X-Gm-Message-State: AOAM533qEBts1XH81YpiL571jAUvM6+0tcak/wuqxnL91E9ahNvxPy7c T5mCGsTDGvuVPaNL94u7x2dbPDtc+WbT3Z7JJoY= X-Received: by 2002:adf:e3cf:: with SMTP id k15mr4464015wrm.291.1599669862021; Wed, 09 Sep 2020 09:44:22 -0700 (PDT) Received: from lmecxl0524.lme.st.com ([2a04:cec0:100d:d03f:c9d0:c7b0:9925:5cde]) by smtp.gmail.com with ESMTPSA id t15sm4468301wmj.15.2020.09.09.09.44.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 09:44:21 -0700 (PDT) From: Etienne Carriere To: u-boot@lists.denx.de Cc: Simon Glass , Lukasz Majewski , Peng Fan , Sudeep Holla , Etienne Carriere Subject: [PATCH v4 8/8] firmware: smci: sandbox test for SCMI reset controllers Date: Wed, 9 Sep 2020 18:44:07 +0200 Message-Id: <20200909164407.14327-8-etienne.carriere@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200909164407.14327-1-etienne.carriere@linaro.org> References: <20200909164407.14327-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 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 Cc: Simon Glass Cc: Peng Fan Cc: Sudeep Holla --- 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(-) -- 2.17.1 Reviewed-by: Simon Glass 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@16 { + reg = <0x16>; + #reset-cells = <1>; + }; }; sandbox-scmi-agent@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@0" in test.dts. + * Agent #0 simulates 2 clocks and 1 reset domain. + * See IDs in scmi0_clk[]/scmi0_reset[] and "sandbox-scmi-agent@0" in test.dts. * * Agent #1 simulates 1 clock. * See IDs in scmi1_clk[] and "sandbox-scmi-agent@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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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);