From patchwork Tue Aug 21 14:31:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960465 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="gMfChosR"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtv336KVz9s5b for ; Wed, 22 Aug 2018 00:52:31 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 21BB3C21E31; Tue, 21 Aug 2018 14:43:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 245C3C21EE7; Tue, 21 Aug 2018 14:36:41 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 23767C21EE5; Tue, 21 Aug 2018 14:33:34 +0000 (UTC) Received: from lelv0143.ext.ti.com (lelv0143.ext.ti.com [198.47.23.248]) by lists.denx.de (Postfix) with ESMTPS id 8FEF6C21E3A for ; Tue, 21 Aug 2018 14:33:27 +0000 (UTC) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXPvJ127788; Tue, 21 Aug 2018 09:33:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1534862005; bh=d/p71E/TOxL0PmUVt5nOY4SJEMaMIqPMyDwLRGuRUO8=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=gMfChosR6LfkAJmVDRGtsUhNcxYB5OJxqWXw0irinz/5LIYRljxeB8USledJRtKf/ QrOtuPeMFZk8xhBemn4HJ4iD5/Zi8/qdMMaXlXOJIm4pmRl2jxHiytHgusDLPQVPQ2 bNfLVsk2ATgmdKACXhU9G7zzHUVkgc2CnuWzm4mc= Received: from DFLE114.ent.ti.com (dfle114.ent.ti.com [10.64.6.35]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXPYY010798; Tue, 21 Aug 2018 09:33:25 -0500 Received: from DFLE112.ent.ti.com (10.64.6.33) by DFLE114.ent.ti.com (10.64.6.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:25 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE112.ent.ti.com (10.64.6.33) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:25 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhM016556; Tue, 21 Aug 2018 09:33:23 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:39 +0530 Message-ID: <20180821143203.29142-2-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 01/25] firmware: Add basic support for TI System Control Interface (TI SCI) protocol X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" Texas Instrument's System Control Interface (TI SCI) message protocol is used in Texas Instrument's System on Chip (SoC) such as those in the K3 family AM654 SoC to communicate between various compute processors with a central system controller entity. The TI SCI message protocol provides support for management of various hardware entities within the SoC. Add support driver to allow communication with system controller entity within the SoC using the mailbox client. This is mostly derived from the TI SCI driver in Linux located at drivers/firmware/ti_sci.c. Signed-off-by: Lokesh Vutla Signed-off-by: Nishanth Menon Signed-off-by: Andreas Dannenberg Reviewed-by: Tom Rini --- doc/device-tree-bindings/firmware/ti,sci.txt | 76 ++++ drivers/firmware/Kconfig | 13 + drivers/firmware/Makefile | 1 + drivers/firmware/ti_sci.c | 448 +++++++++++++++++++ drivers/firmware/ti_sci.h | 80 ++++ include/linux/soc/ti/ti_sci_protocol.h | 69 +++ 6 files changed, 687 insertions(+) create mode 100644 doc/device-tree-bindings/firmware/ti,sci.txt create mode 100644 drivers/firmware/ti_sci.c create mode 100644 drivers/firmware/ti_sci.h create mode 100644 include/linux/soc/ti/ti_sci_protocol.h diff --git a/doc/device-tree-bindings/firmware/ti,sci.txt b/doc/device-tree-bindings/firmware/ti,sci.txt new file mode 100644 index 0000000000..4d40d0dcb6 --- /dev/null +++ b/doc/device-tree-bindings/firmware/ti,sci.txt @@ -0,0 +1,76 @@ +Texas Instruments System Control Interface (TI-SCI) Message Protocol +-------------------------------------------------------------------- + +Texas Instrument's processors including those belonging to Keystone generation +of processors have separate hardware entity which is now responsible for the +management of the System on Chip (SoC) system. These include various system +level functions as well. + +An example of such an SoC is K2G, which contains the system control hardware +block called Power Management Micro Controller (PMMC). This hardware block is +initialized early into boot process and provides services to Operating Systems +on multiple processors including ones running Linux. + +See http://processors.wiki.ti.com/index.php/TISCI for protocol definition. + +TI-SCI controller Device Node: +============================= + +The TI-SCI node describes the Texas Instrument's System Controller entity node. +This parent node may optionally have additional children nodes which describe +specific functionality such as clocks, power domain, reset or additional +functionality as may be required for the SoC. This hierarchy also describes the +relationship between the TI-SCI parent node to the child node. + +Required properties: +------------------- +- compatible: should be "ti,k2g-sci" +- mbox-names: + "rx" - Mailbox corresponding to receive path + "tx" - Mailbox corresponding to transmit path + +- mboxes: Mailboxes corresponding to the mbox-names. Each value of the mboxes + property should contain a phandle to the mailbox controller device + node and an args specifier that will be the phandle to the intended + sub-mailbox child node to be used for communication. + +Optional Properties: +------------------- +- reg-names: + debug_messages - Map the Debug message region +- reg: register space corresponding to the debug_messages +- ti,system-reboot-controller: If system reboot can be triggered by SoC reboot +- ti,secure-host: If the host is defined as secure. + +Example: +------------- + dmsc: dmsc { + compatible = "ti,k2g-sci"; + ti,host-id = <12>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + } + + +TI-SCI Client Device Node: +========================= + +Client nodes are maintained as children of the relevant TI-SCI device node. + +Example: +------------- + dmsc: dmsc { + compatible = "ti,k2g-sci"; + ... + + my_clk_node: clk_node { + ... + ... + }; + + my_pd_node: pd_node { + ... + ... + }; + }; diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 4c32426e0e..cb73b70f5b 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -4,3 +4,16 @@ config FIRMWARE config ARM_PSCI_FW bool select FIRMWARE + +config TI_SCI_PROTOCOL + tristate "TI System Control Interface (TISCI) Message Protocol" + depends on K3_SEC_PROXY + select FIRMWARE + help + TI System Control Interface (TISCI) Message Protocol is used to manage + compute systems such as ARM, DSP etc with the system controller in + complex System on Chip (SoC) such as those found on certain K3 + generation SoC from TI. + + This protocol library is used by client drivers to use the features + provided by the system controller. diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index b208255368..1cdda14977 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_FIRMWARE) += firmware-uclass.o obj-$(CONFIG_ARM_PSCI_FW) += psci.o +obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c new file mode 100644 index 0000000000..c1169987ad --- /dev/null +++ b/drivers/firmware/ti_sci.c @@ -0,0 +1,448 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Texas Instruments System Control Interface Protocol Driver + * Based on drivers/firmware/ti_sci.c from Linux. + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Lokesh Vutla + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ti_sci.h" + +/* List of all TI SCI devices active in system */ +static LIST_HEAD(ti_sci_list); + +/** + * struct ti_sci_xfer - Structure representing a message flow + * @tx_message: Transmit message + * @rx_len: Receive message length + */ +struct ti_sci_xfer { + struct k3_sec_proxy_msg tx_message; + u8 rx_len; +}; + +/** + * struct ti_sci_desc - Description of SoC integration + * @host_id: Host identifier representing the compute entity + * @max_rx_timeout_us: Timeout for communication with SoC (in Microseconds) + * @max_msg_size: Maximum size of data per message that can be handled. + */ +struct ti_sci_desc { + u8 host_id; + int max_rx_timeout_us; + int max_msg_size; +}; + +/** + * struct ti_sci_info - Structure representing a TI SCI instance + * @dev: Device pointer + * @desc: SoC description for this instance + * @handle: Instance of TI SCI handle to send to clients. + * @chan_tx: Transmit mailbox channel + * @chan_rx: Receive mailbox channel + * @xfer: xfer info + * @list: list head + * @is_secure: Determines if the communication is through secure threads. + * @host_id: Host identifier representing the compute entity + * @seq: Seq id used for verification for tx and rx message. + */ +struct ti_sci_info { + struct udevice *dev; + const struct ti_sci_desc *desc; + struct ti_sci_handle handle; + struct mbox_chan chan_tx; + struct mbox_chan chan_rx; + struct mbox_chan chan_notify; + struct ti_sci_xfer xfer; + struct list_head list; + bool is_secure; + u8 host_id; + u8 seq; +}; + +#define handle_to_ti_sci_info(h) container_of(h, struct ti_sci_info, handle) + +/** + * ti_sci_setup_one_xfer() - Setup one message type + * @info: Pointer to SCI entity information + * @msg_type: Message type + * @msg_flags: Flag to set for the message + * @buf: Buffer to be send to mailbox channel + * @tx_message_size: transmit message size + * @rx_message_size: receive message size + * + * Helper function which is used by various command functions that are + * exposed to clients of this driver for allocating a message traffic event. + * + * Return: Corresponding ti_sci_xfer pointer if all went fine, + * else appropriate error pointer. + */ +static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info, + u16 msg_type, u32 msg_flags, + u32 *buf, + size_t tx_message_size, + size_t rx_message_size) +{ + struct ti_sci_xfer *xfer = &info->xfer; + struct ti_sci_msg_hdr *hdr; + + /* Ensure we have sane transfer sizes */ + if (rx_message_size > info->desc->max_msg_size || + tx_message_size > info->desc->max_msg_size || + rx_message_size < sizeof(*hdr) || tx_message_size < sizeof(*hdr)) + return ERR_PTR(-ERANGE); + + info->seq = ~info->seq; + xfer->tx_message.buf = buf; + xfer->tx_message.len = tx_message_size; + xfer->rx_len = (u8)rx_message_size; + + hdr = (struct ti_sci_msg_hdr *)buf; + hdr->seq = info->seq; + hdr->type = msg_type; + hdr->host = info->host_id; + hdr->flags = msg_flags; + + return xfer; +} + +/** + * ti_sci_get_response() - Receive response from mailbox channel + * @info: Pointer to SCI entity information + * @xfer: Transfer to initiate and wait for response + * @chan: Channel to receive the response + * + * Return: -ETIMEDOUT in case of no response, if transmit error, + * return corresponding error, else if all goes well, + * return 0. + */ +static inline int ti_sci_get_response(struct ti_sci_info *info, + struct ti_sci_xfer *xfer, + struct mbox_chan *chan) +{ + struct k3_sec_proxy_msg *msg = &xfer->tx_message; + struct ti_sci_secure_msg_hdr *secure_hdr; + struct ti_sci_msg_hdr *hdr; + int ret; + + /* Receive the response */ + ret = mbox_recv(chan, msg, info->desc->max_rx_timeout_us); + if (ret) { + dev_err(info->dev, "%s: Message receive failed. ret = %d\n", + __func__, ret); + return ret; + } + + /* ToDo: Verify checksum */ + if (info->is_secure) { + secure_hdr = (struct ti_sci_secure_msg_hdr *)msg->buf; + msg->buf = (u32 *)((void *)msg->buf + sizeof(*secure_hdr)); + } + + /* msg is updated by mailbox driver */ + hdr = (struct ti_sci_msg_hdr *)msg->buf; + + /* Sanity check for message response */ + if (hdr->seq != info->seq) { + dev_dbg(info->dev, "%s: Message for %d is not expected\n", + __func__, hdr->seq); + return ret; + } + + if (msg->len > info->desc->max_msg_size) { + dev_err(info->dev, "%s: Unable to handle %zu xfer (max %d)\n", + __func__, msg->len, info->desc->max_msg_size); + return -EINVAL; + } + + if (msg->len < xfer->rx_len) { + dev_err(info->dev, "%s: Recv xfer %zu < expected %d length\n", + __func__, msg->len, xfer->rx_len); + } + + return ret; +} + +/** + * ti_sci_do_xfer() - Do one transfer + * @info: Pointer to SCI entity information + * @xfer: Transfer to initiate and wait for response + * + * Return: 0 if all went fine, else return appropriate error. + */ +static inline int ti_sci_do_xfer(struct ti_sci_info *info, + struct ti_sci_xfer *xfer) +{ + struct k3_sec_proxy_msg *msg = &xfer->tx_message; + u8 secure_buf[info->desc->max_msg_size]; + struct ti_sci_secure_msg_hdr secure_hdr; + int ret; + + if (info->is_secure) { + /* ToDo: get checksum of the entire message */ + secure_hdr.checksum = 0; + secure_hdr.reserved = 0; + memcpy(&secure_buf[sizeof(secure_hdr)], xfer->tx_message.buf, + xfer->tx_message.len); + + xfer->tx_message.buf = (u32 *)secure_buf; + xfer->tx_message.len += sizeof(secure_hdr); + xfer->rx_len += sizeof(secure_hdr); + } + + /* Send the message */ + ret = mbox_send(&info->chan_tx, msg); + if (ret) { + dev_err(info->dev, "%s: Message sending failed. ret = %d\n", + __func__, ret); + return ret; + } + + return ti_sci_get_response(info, xfer, &info->chan_rx); +} + +/** + * ti_sci_cmd_get_revision() - command to get the revision of the SCI entity + * @handle: pointer to TI SCI handle + * + * Updates the SCI information in the internal data structure. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle) +{ + struct ti_sci_msg_resp_version *rev_info; + struct ti_sci_version_info *ver; + struct ti_sci_msg_hdr hdr; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_VERSION, 0x0, + (u32 *)&hdr, sizeof(struct ti_sci_msg_hdr), + sizeof(*rev_info)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox communication fail %d\n", ret); + return ret; + } + + rev_info = (struct ti_sci_msg_resp_version *)xfer->tx_message.buf; + + ver = &handle->version; + ver->abi_major = rev_info->abi_major; + ver->abi_minor = rev_info->abi_minor; + ver->firmware_revision = rev_info->firmware_revision; + strncpy(ver->firmware_description, rev_info->firmware_description, + sizeof(ver->firmware_description)); + + return 0; +} + +/** + * ti_sci_is_response_ack() - Generic ACK/NACK message checkup + * @r: pointer to response buffer + * + * Return: true if the response was an ACK, else returns false. + */ +static inline bool ti_sci_is_response_ack(void *r) +{ + struct ti_sci_msg_hdr *hdr = r; + + return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false; +} + +/** + * ti_sci_get_handle_from_sysfw() - Get the TI SCI handle of the SYSFW + * @dev: Pointer to the SYSFW device + * + * Return: pointer to handle if successful, else EINVAL if invalid conditions + * are encountered. + */ +const +struct ti_sci_handle *ti_sci_get_handle_from_sysfw(struct udevice *sci_dev) +{ + if (!sci_dev) + return ERR_PTR(-EINVAL); + + struct ti_sci_info *info = dev_get_priv(sci_dev); + + if (!info) + return ERR_PTR(-EINVAL); + + struct ti_sci_handle *handle = &info->handle; + + if (!handle) + return ERR_PTR(-EINVAL); + + return handle; +} + +/** + * ti_sci_get_handle() - Get the TI SCI handle for a device + * @dev: Pointer to device for which we want SCI handle + * + * Return: pointer to handle if successful, else EINVAL if invalid conditions + * are encountered. + */ +const struct ti_sci_handle *ti_sci_get_handle(struct udevice *dev) +{ + if (!dev) + return ERR_PTR(-EINVAL); + + struct udevice *sci_dev = dev_get_parent(dev); + + return ti_sci_get_handle_from_sysfw(sci_dev); +} + +/** + * ti_sci_get_by_phandle() - Get the TI SCI handle using DT phandle + * @dev: device node + * @propname: property name containing phandle on TISCI node + * + * Return: pointer to handle if successful, else appropriate error value. + */ +const struct ti_sci_handle *ti_sci_get_by_phandle(struct udevice *dev, + const char *property) +{ + struct ti_sci_info *entry, *info = NULL; + u32 phandle, err; + ofnode node; + + err = ofnode_read_u32(dev_ofnode(dev), property, &phandle); + if (err) + return ERR_PTR(err); + + node = ofnode_get_by_phandle(phandle); + if (!ofnode_valid(node)) + return ERR_PTR(-EINVAL); + + list_for_each_entry(entry, &ti_sci_list, list) + if (ofnode_equal(dev_ofnode(entry->dev), node)) { + info = entry; + break; + } + + if (!info) + return ERR_PTR(-ENODEV); + + return &info->handle; +} + +/** + * ti_sci_of_to_info() - generate private data from device tree + * @dev: corresponding system controller interface device + * @info: pointer to driver specific private data + * + * Return: 0 if all goes good, else appropriate error message. + */ +static int ti_sci_of_to_info(struct udevice *dev, struct ti_sci_info *info) +{ + int ret; + + ret = mbox_get_by_name(dev, "tx", &info->chan_tx); + if (ret) { + dev_err(dev, "%s: Acquiring Tx channel failed. ret = %d\n", + __func__, ret); + return ret; + } + + ret = mbox_get_by_name(dev, "rx", &info->chan_rx); + if (ret) { + dev_err(dev, "%s: Acquiring Rx channel failed. ret = %d\n", + __func__, ret); + return ret; + } + + /* Notify channel is optional. Enable only if populated */ + ret = mbox_get_by_name(dev, "notify", &info->chan_notify); + if (ret) { + dev_dbg(dev, "%s: Acquiring notify channel failed. ret = %d\n", + __func__, ret); + } + + info->host_id = dev_read_u32_default(dev, "ti,host-id", + info->desc->host_id); + + info->is_secure = dev_read_bool(dev, "ti,secure-host"); + + return 0; +} + +/** + * ti_sci_probe() - Basic probe + * @dev: corresponding system controller interface device + * + * Return: 0 if all goes good, else appropriate error message. + */ +static int ti_sci_probe(struct udevice *dev) +{ + struct ti_sci_info *info; + int ret; + + debug("%s(dev=%p)\n", __func__, dev); + + info = dev_get_priv(dev); + info->desc = (void *)dev_get_driver_data(dev); + + ret = ti_sci_of_to_info(dev, info); + if (ret) { + dev_err(dev, "%s: Probe failed with error %d\n", __func__, ret); + return ret; + } + + info->dev = dev; + info->seq = 0xA; + + list_add_tail(&info->list, &ti_sci_list); + + ret = ti_sci_cmd_get_revision(&info->handle); + + return ret; +} + +/* Description for AM654 */ +static const struct ti_sci_desc ti_sci_sysfw_am654_desc = { + .host_id = 4, + .max_rx_timeout_us = 1000000, + .max_msg_size = 60, +}; + +static const struct udevice_id ti_sci_ids[] = { + { + .compatible = "ti,k2g-sci", + .data = (ulong)&ti_sci_sysfw_am654_desc + }, + { /* Sentinel */ }, +}; + +U_BOOT_DRIVER(ti_sci) = { + .name = "ti_sci", + .id = UCLASS_FIRMWARE, + .of_match = ti_sci_ids, + .probe = ti_sci_probe, + .priv_auto_alloc_size = sizeof(struct ti_sci_info), +}; diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h new file mode 100644 index 0000000000..0f81da9ecd --- /dev/null +++ b/drivers/firmware/ti_sci.h @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Texas Instruments System Control Interface (TISCI) Protocol + * + * Communication protocol with TI SCI hardware + * The system works in a message response protocol + * See: http://processors.wiki.ti.com/index.php/TISCI for details + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Based on drivers/firmware/ti_sci.h from Linux. + * + */ + +#ifndef __TI_SCI_H +#define __TI_SCI_H + +/* Generic Messages */ +#define TI_SCI_MSG_ENABLE_WDT 0x0000 +#define TI_SCI_MSG_WAKE_RESET 0x0001 +#define TI_SCI_MSG_VERSION 0x0002 +#define TI_SCI_MSG_WAKE_REASON 0x0003 +#define TI_SCI_MSG_GOODBYE 0x0004 +#define TI_SCI_MSG_SYS_RESET 0x0005 +#define TI_SCI_MSG_BOARD_CONFIG 0x000b + +/** + * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses + * @type: Type of messages: One of TI_SCI_MSG* values + * @host: Host of the message + * @seq: Message identifier indicating a transfer sequence + * @flags: Flag for the message + */ +struct ti_sci_msg_hdr { + u16 type; + u8 host; + u8 seq; +#define TI_SCI_MSG_FLAG(val) (1 << (val)) +#define TI_SCI_FLAG_REQ_GENERIC_NORESPONSE 0x0 +#define TI_SCI_FLAG_REQ_ACK_ON_RECEIVED TI_SCI_MSG_FLAG(0) +#define TI_SCI_FLAG_REQ_ACK_ON_PROCESSED TI_SCI_MSG_FLAG(1) +#define TI_SCI_FLAG_RESP_GENERIC_NACK 0x0 +#define TI_SCI_FLAG_RESP_GENERIC_ACK TI_SCI_MSG_FLAG(1) + /* Additional Flags */ + u32 flags; +} __packed; + +/** + * struct ti_sci_secure_msg_hdr - Header that prefixes all TISCI messages sent + * via secure transport. + * @checksum: crc16 checksum for the entire message + * @reserved: Reserved for future use. + */ +struct ti_sci_secure_msg_hdr { + u16 checksum; + u16 reserved; +} __packed; + +/** + * struct ti_sci_msg_resp_version - Response for a message + * @hdr: Generic header + * @firmware_description: String describing the firmware + * @firmware_revision: Firmware revision + * @abi_major: Major version of the ABI that firmware supports + * @abi_minor: Minor version of the ABI that firmware supports + * + * In general, ABI version changes follow the rule that minor version increments + * are backward compatible. Major revision changes in ABI may not be + * backward compatible. + * + * Response to a generic message with message type TI_SCI_MSG_VERSION + */ +struct ti_sci_msg_resp_version { + struct ti_sci_msg_hdr hdr; + char firmware_description[32]; + u16 firmware_revision; + u8 abi_major; + u8 abi_minor; +} __packed; + +#endif /* __TI_SCI_H */ diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h new file mode 100644 index 0000000000..7ab141049a --- /dev/null +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -0,0 +1,69 @@ +/* + * Texas Instruments System Control Interface Protocol + * Based on include/linux/soc/ti/ti_sci_protocol.h from Linux. + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Nishanth Menon + * Lokesh Vutla + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __TISCI_PROTOCOL_H +#define __TISCI_PROTOCOL_H + +/** + * struct ti_sci_version_info - version information structure + * @abi_major: Major ABI version. Change here implies risk of backward + * compatibility break. + * @abi_minor: Minor ABI version. Change here implies new feature addition, + * or compatible change in ABI. + * @firmware_revision: Firmware revision (not usually used). + * @firmware_description: Firmware description (not usually used). + */ +struct ti_sci_version_info { + u8 abi_major; + u8 abi_minor; + u16 firmware_revision; + char firmware_description[32]; +}; + +struct ti_sci_handle; + +/** + * struct ti_sci_handle - Handle returned to TI SCI clients for usage. + * @version: structure containing version information + */ +struct ti_sci_handle { + struct ti_sci_version_info version; +}; + +#if IS_ENABLED(CONFIG_TI_SCI_PROTOCOL) + +const struct ti_sci_handle *ti_sci_get_handle_from_sysfw(struct udevice *dev); +const struct ti_sci_handle *ti_sci_get_handle(struct udevice *dev); +const struct ti_sci_handle *ti_sci_get_by_phandle(struct udevice *dev, + const char *property); + +#else /* CONFIG_TI_SCI_PROTOCOL */ + +static inline +const struct ti_sci_handle *ti_sci_get_handle_from_sysfw(struct udevice *dev) +{ + return ERR_PTR(-EINVAL); +} + +static inline const struct ti_sci_handle *ti_sci_get_handle(struct udevice *dev) +{ + return ERR_PTR(-EINVAL); +} + +static inline +const struct ti_sci_handle *ti_sci_get_by_phandle(struct udevice *dev, + const char *property) +{ + return ERR_PTR(-EINVAL); +} +#endif /* CONFIG_TI_SCI_PROTOCOL */ + +#endif /* __TISCI_PROTOCOL_H */ From patchwork Tue Aug 21 14:31:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960473 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtzl3tc1z9s3x for ; Wed, 22 Aug 2018 00:56:35 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id E8C5EC21E2C; Tue, 21 Aug 2018 14:40:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 06581C21E2C; Tue, 21 Aug 2018 14:35:01 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 1DB98C21E30; Tue, 21 Aug 2018 14:33:33 +0000 (UTC) Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) by lists.denx.de (Postfix) with ESMTPS id 6DD66C21E34 for ; Tue, 21 Aug 2018 14:33:29 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXSmG044204; Tue, 21 Aug 2018 09:33:28 -0500 Received: from DLEE107.ent.ti.com (dlee107.ent.ti.com [157.170.170.37]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXRYx018550; Tue, 21 Aug 2018 09:33:27 -0500 Received: from DLEE107.ent.ti.com (157.170.170.37) by DLEE107.ent.ti.com (157.170.170.37) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:27 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE107.ent.ti.com (157.170.170.37) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:27 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhN016556; Tue, 21 Aug 2018 09:33:25 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:40 +0530 Message-ID: <20180821143203.29142-3-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 02/25] firmware: ti_sci: Add support for board configuration X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Andreas Dannenberg TI-SCI message protocol provides support for board configuration to assign resources and other board related operations. Introduce the board configuration capability support to the driver protocol as part of this change. Signed-off-by: Andreas Dannenberg Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- drivers/firmware/ti_sci.c | 137 +++++++++++++++++++++++++ drivers/firmware/ti_sci.h | 21 ++++ include/linux/soc/ti/ti_sci_protocol.h | 38 +++++++ 3 files changed, 196 insertions(+) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index c1169987ad..ce7483307e 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -275,6 +275,142 @@ static inline bool ti_sci_is_response_ack(void *r) return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false; } +/** + * cmd_set_board_config_using_msg() - Common command to send board configuration + * message + * @handle: pointer to TI SCI handle + * @msg_type: One of the TISCI message types to set board configuration + * @addr: Address where the board config structure is located + * @size: Size of the board config structure + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int cmd_set_board_config_using_msg(const struct ti_sci_handle *handle, + u16 msg_type, u64 addr, u32 size) +{ + struct ti_sci_msg_board_config req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, msg_type, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.boardcfgp_high = (addr >> 32) & 0xffffffff; + req.boardcfgp_low = addr & 0xffffffff; + req.boardcfg_size = size; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + return -ENODEV; + + return ret; +} + +/** + * ti_sci_cmd_set_board_config() - Command to send board configuration message + * @handle: pointer to TI SCI handle + * @addr: Address where the board config structure is located + * @size: Size of the board config structure + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_set_board_config(const struct ti_sci_handle *handle, + u64 addr, u32 size) +{ + return cmd_set_board_config_using_msg(handle, + TI_SCI_MSG_BOARD_CONFIG, + addr, size); +} + +/** + * ti_sci_cmd_set_board_config_rm() - Command to send board resource + * management configuration + * @handle: pointer to TI SCI handle + * @addr: Address where the board RM config structure is located + * @size: Size of the RM config structure + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static +int ti_sci_cmd_set_board_config_rm(const struct ti_sci_handle *handle, + u64 addr, u32 size) +{ + return cmd_set_board_config_using_msg(handle, + TI_SCI_MSG_BOARD_CONFIG_RM, + addr, size); +} + +/** + * ti_sci_cmd_set_board_config_security() - Command to send board security + * configuration message + * @handle: pointer to TI SCI handle + * @addr: Address where the board security config structure is located + * @size: Size of the security config structure + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static +int ti_sci_cmd_set_board_config_security(const struct ti_sci_handle *handle, + u64 addr, u32 size) +{ + return cmd_set_board_config_using_msg(handle, + TI_SCI_MSG_BOARD_CONFIG_SECURITY, + addr, size); +} + +/** + * ti_sci_cmd_set_board_config_pm() - Command to send board power and clock + * configuration message + * @handle: pointer to TI SCI handle + * @addr: Address where the board PM config structure is located + * @size: Size of the PM config structure + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_set_board_config_pm(const struct ti_sci_handle *handle, + u64 addr, u32 size) +{ + return cmd_set_board_config_using_msg(handle, + TI_SCI_MSG_BOARD_CONFIG_PM, + addr, size); +} + +/* + * ti_sci_setup_ops() - Setup the operations structures + * @info: pointer to TISCI pointer + */ +static void ti_sci_setup_ops(struct ti_sci_info *info) +{ + struct ti_sci_ops *ops = &info->handle.ops; + struct ti_sci_board_ops *bops = &ops->board_ops; + + bops->board_config = ti_sci_cmd_set_board_config; + bops->board_config_rm = ti_sci_cmd_set_board_config_rm; + bops->board_config_security = ti_sci_cmd_set_board_config_security; + bops->board_config_pm = ti_sci_cmd_set_board_config_pm; +} + /** * ti_sci_get_handle_from_sysfw() - Get the TI SCI handle of the SYSFW * @dev: Pointer to the SYSFW device @@ -418,6 +554,7 @@ static int ti_sci_probe(struct udevice *dev) info->seq = 0xA; list_add_tail(&info->list, &ti_sci_list); + ti_sci_setup_ops(info); ret = ti_sci_cmd_get_revision(&info->handle); diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index 0f81da9ecd..4377665d65 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -22,6 +22,9 @@ #define TI_SCI_MSG_GOODBYE 0x0004 #define TI_SCI_MSG_SYS_RESET 0x0005 #define TI_SCI_MSG_BOARD_CONFIG 0x000b +#define TI_SCI_MSG_BOARD_CONFIG_RM 0x000c +#define TI_SCI_MSG_BOARD_CONFIG_SECURITY 0x000d +#define TI_SCI_MSG_BOARD_CONFIG_PM 0x000e /** * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses @@ -77,4 +80,22 @@ struct ti_sci_msg_resp_version { u8 abi_minor; } __packed; +/** + * struct ti_sci_msg_board_config - Board configuration message + * @hdr: Generic Header + * @boardcfgp_low: Lower 32 bit of the pointer pointing to the board + * configuration data + * @boardcfgp_high: Upper 32 bit of the pointer pointing to the board + * configuration data + * @boardcfg_size: Size of board configuration data object + * Request type is TI_SCI_MSG_BOARD_CONFIG, responded with a generic + * ACK/NACK message. + */ +struct ti_sci_msg_board_config { + struct ti_sci_msg_hdr hdr; + u32 boardcfgp_low; + u32 boardcfgp_high; + u16 boardcfg_size; +} __packed; + #endif /* __TI_SCI_H */ diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index 7ab141049a..88b940fb8e 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -30,11 +30,49 @@ struct ti_sci_version_info { struct ti_sci_handle; +/** + * struct ti_sci_board_ops - Board config operations + * @board_config: Command to set the board configuration + * Returns 0 for successful exclusive request, else returns + * corresponding error message. + * @board_config_rm: Command to set the board resource management + * configuration + * Returns 0 for successful exclusive request, else returns + * corresponding error message. + * @board_config_security: Command to set the board security configuration + * Returns 0 for successful exclusive request, else returns + * corresponding error message. + * @board_config_pm: Command to trigger and set the board power and clock + * management related configuration + * Returns 0 for successful exclusive request, else returns + * corresponding error message. + */ +struct ti_sci_board_ops { + int (*board_config)(const struct ti_sci_handle *handle, + u64 addr, u32 size); + int (*board_config_rm)(const struct ti_sci_handle *handle, + u64 addr, u32 size); + int (*board_config_security)(const struct ti_sci_handle *handle, + u64 addr, u32 size); + int (*board_config_pm)(const struct ti_sci_handle *handle, + u64 addr, u32 size); +}; + +/** + * struct ti_sci_ops - Function support for TI SCI + * @board_ops: Miscellaneous operations + */ +struct ti_sci_ops { + struct ti_sci_board_ops board_ops; +}; + /** * struct ti_sci_handle - Handle returned to TI SCI clients for usage. + * @ops: operations that are made available to TI SCI clients * @version: structure containing version information */ struct ti_sci_handle { + struct ti_sci_ops ops; struct ti_sci_version_info version; }; From patchwork Tue Aug 21 14:31:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960439 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vthR6rQ2z9s5b for ; Wed, 22 Aug 2018 00:43:19 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 8AF63C21C4A; Tue, 21 Aug 2018 14:39:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id D16F4C21E1E; Tue, 21 Aug 2018 14:34:51 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id E0846C21E12; Tue, 21 Aug 2018 14:33:36 +0000 (UTC) Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) by lists.denx.de (Postfix) with ESMTPS id C1B17C21E35 for ; Tue, 21 Aug 2018 14:33:31 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXUDd044213; Tue, 21 Aug 2018 09:33:30 -0500 Received: from DFLE104.ent.ti.com (dfle104.ent.ti.com [10.64.6.25]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXU2a018616; Tue, 21 Aug 2018 09:33:30 -0500 Received: from DFLE108.ent.ti.com (10.64.6.29) by DFLE104.ent.ti.com (10.64.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:29 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE108.ent.ti.com (10.64.6.29) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:30 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhO016556; Tue, 21 Aug 2018 09:33:28 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:41 +0530 Message-ID: <20180821143203.29142-4-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 03/25] firmware: ti_sci: Add support for device control X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Andreas Dannenberg TI-SCI message protocol provides support for management of various hardware entitites within the SoC. Introduce the fundamental device management capability support to the driver protocol as part of this change. Signed-off-by: Lokesh Vutla Signed-off-by: Nishanth Menon Reviewed-by: Tom Rini --- drivers/firmware/ti_sci.c | 391 +++++++++++++++++++++++++ drivers/firmware/ti_sci.h | 98 +++++++ include/linux/soc/ti/ti_sci_protocol.h | 81 +++++ 3 files changed, 570 insertions(+) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index ce7483307e..fc55b0f67a 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -396,6 +396,384 @@ static int ti_sci_cmd_set_board_config_pm(const struct ti_sci_handle *handle, addr, size); } +/** + * ti_sci_set_device_state() - Set device state helper + * @handle: pointer to TI SCI handle + * @id: Device identifier + * @flags: flags to setup for the device + * @state: State to move the device to + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_set_device_state(const struct ti_sci_handle *handle, + u32 id, u32 flags, u8 state) +{ + struct ti_sci_msg_req_set_device_state req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE, + flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.id = id; + req.state = state; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + return -ENODEV; + + return ret; +} + +/** + * ti_sci_get_device_state() - Get device state helper + * @handle: Handle to the device + * @id: Device Identifier + * @clcnt: Pointer to Context Loss Count + * @resets: pointer to resets + * @p_state: pointer to p_state + * @c_state: pointer to c_state + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_get_device_state(const struct ti_sci_handle *handle, + u32 id, u32 *clcnt, u32 *resets, + u8 *p_state, u8 *c_state) +{ + struct ti_sci_msg_resp_get_device_state *resp; + struct ti_sci_msg_req_get_device_state req; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + if (!clcnt && !resets && !p_state && !c_state) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + /* Response is expected, so need of any flags */ + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_DEVICE_STATE, 0, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.id = id; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_resp_get_device_state *)xfer->tx_message.buf; + if (!ti_sci_is_response_ack(resp)) + return -ENODEV; + + if (clcnt) + *clcnt = resp->context_loss_count; + if (resets) + *resets = resp->resets; + if (p_state) + *p_state = resp->programmed_state; + if (c_state) + *c_state = resp->current_state; + + return ret; +} + +/** + * ti_sci_cmd_get_device() - command to request for device managed by TISCI + * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle + * @id: Device Identifier + * + * Request for the device - NOTE: the client MUST maintain integrity of + * usage count by balancing get_device with put_device. No refcounting is + * managed by driver for that purpose. + * + * NOTE: The request is for exclusive access for the processor. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id) +{ + return ti_sci_set_device_state(handle, id, + MSG_FLAG_DEVICE_EXCLUSIVE, + MSG_DEVICE_SW_STATE_ON); +} + +/** + * ti_sci_cmd_idle_device() - Command to idle a device managed by TISCI + * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle + * @id: Device Identifier + * + * Request for the device - NOTE: the client MUST maintain integrity of + * usage count by balancing get_device with put_device. No refcounting is + * managed by driver for that purpose. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id) +{ + return ti_sci_set_device_state(handle, id, + MSG_FLAG_DEVICE_EXCLUSIVE, + MSG_DEVICE_SW_STATE_RETENTION); +} + +/** + * ti_sci_cmd_put_device() - command to release a device managed by TISCI + * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle + * @id: Device Identifier + * + * Request for the device - NOTE: the client MUST maintain integrity of + * usage count by balancing get_device with put_device. No refcounting is + * managed by driver for that purpose. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_put_device(const struct ti_sci_handle *handle, u32 id) +{ + return ti_sci_set_device_state(handle, id, + 0, MSG_DEVICE_SW_STATE_AUTO_OFF); +} + +/** + * ti_sci_cmd_dev_is_valid() - Is the device valid + * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle + * @id: Device Identifier + * + * Return: 0 if all went fine and the device ID is valid, else return + * appropriate error. + */ +static int ti_sci_cmd_dev_is_valid(const struct ti_sci_handle *handle, u32 id) +{ + u8 unused; + + /* check the device state which will also tell us if the ID is valid */ + return ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &unused); +} + +/** + * ti_sci_cmd_dev_get_clcnt() - Get context loss counter + * @handle: Pointer to TISCI handle + * @id: Device Identifier + * @count: Pointer to Context Loss counter to populate + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_dev_get_clcnt(const struct ti_sci_handle *handle, u32 id, + u32 *count) +{ + return ti_sci_get_device_state(handle, id, count, NULL, NULL, NULL); +} + +/** + * ti_sci_cmd_dev_is_idle() - Check if the device is requested to be idle + * @handle: Pointer to TISCI handle + * @id: Device Identifier + * @r_state: true if requested to be idle + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_dev_is_idle(const struct ti_sci_handle *handle, u32 id, + bool *r_state) +{ + int ret; + u8 state; + + if (!r_state) + return -EINVAL; + + ret = ti_sci_get_device_state(handle, id, NULL, NULL, &state, NULL); + if (ret) + return ret; + + *r_state = (state == MSG_DEVICE_SW_STATE_RETENTION); + + return 0; +} + +/** + * ti_sci_cmd_dev_is_stop() - Check if the device is requested to be stopped + * @handle: Pointer to TISCI handle + * @id: Device Identifier + * @r_state: true if requested to be stopped + * @curr_state: true if currently stopped. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_dev_is_stop(const struct ti_sci_handle *handle, u32 id, + bool *r_state, bool *curr_state) +{ + int ret; + u8 p_state, c_state; + + if (!r_state && !curr_state) + return -EINVAL; + + ret = + ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state); + if (ret) + return ret; + + if (r_state) + *r_state = (p_state == MSG_DEVICE_SW_STATE_AUTO_OFF); + if (curr_state) + *curr_state = (c_state == MSG_DEVICE_HW_STATE_OFF); + + return 0; +} + +/** + * ti_sci_cmd_dev_is_on() - Check if the device is requested to be ON + * @handle: Pointer to TISCI handle + * @id: Device Identifier + * @r_state: true if requested to be ON + * @curr_state: true if currently ON and active + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_dev_is_on(const struct ti_sci_handle *handle, u32 id, + bool *r_state, bool *curr_state) +{ + int ret; + u8 p_state, c_state; + + if (!r_state && !curr_state) + return -EINVAL; + + ret = + ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state); + if (ret) + return ret; + + if (r_state) + *r_state = (p_state == MSG_DEVICE_SW_STATE_ON); + if (curr_state) + *curr_state = (c_state == MSG_DEVICE_HW_STATE_ON); + + return 0; +} + +/** + * ti_sci_cmd_dev_is_trans() - Check if the device is currently transitioning + * @handle: Pointer to TISCI handle + * @id: Device Identifier + * @curr_state: true if currently transitioning. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_dev_is_trans(const struct ti_sci_handle *handle, u32 id, + bool *curr_state) +{ + int ret; + u8 state; + + if (!curr_state) + return -EINVAL; + + ret = ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &state); + if (ret) + return ret; + + *curr_state = (state == MSG_DEVICE_HW_STATE_TRANS); + + return 0; +} + +/** + * ti_sci_cmd_set_device_resets() - command to set resets for device managed + * by TISCI + * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle + * @id: Device Identifier + * @reset_state: Device specific reset bit field + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle, + u32 id, u32 reset_state) +{ + struct ti_sci_msg_req_set_device_resets req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_DEVICE_RESETS, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.id = id; + req.resets = reset_state; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + return -ENODEV; + + return ret; +} + +/** + * ti_sci_cmd_get_device_resets() - Get reset state for device managed + * by TISCI + * @handle: Pointer to TISCI handle + * @id: Device Identifier + * @reset_state: Pointer to reset state to populate + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_get_device_resets(const struct ti_sci_handle *handle, + u32 id, u32 *reset_state) +{ + return ti_sci_get_device_state(handle, id, NULL, reset_state, NULL, + NULL); +} + /* * ti_sci_setup_ops() - Setup the operations structures * @info: pointer to TISCI pointer @@ -404,11 +782,24 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) { struct ti_sci_ops *ops = &info->handle.ops; struct ti_sci_board_ops *bops = &ops->board_ops; + struct ti_sci_dev_ops *dops = &ops->dev_ops; bops->board_config = ti_sci_cmd_set_board_config; bops->board_config_rm = ti_sci_cmd_set_board_config_rm; bops->board_config_security = ti_sci_cmd_set_board_config_security; bops->board_config_pm = ti_sci_cmd_set_board_config_pm; + + dops->get_device = ti_sci_cmd_get_device; + dops->idle_device = ti_sci_cmd_idle_device; + dops->put_device = ti_sci_cmd_put_device; + dops->is_valid = ti_sci_cmd_dev_is_valid; + dops->get_context_loss_count = ti_sci_cmd_dev_get_clcnt; + dops->is_idle = ti_sci_cmd_dev_is_idle; + dops->is_stop = ti_sci_cmd_dev_is_stop; + dops->is_on = ti_sci_cmd_dev_is_on; + dops->is_transitioning = ti_sci_cmd_dev_is_trans; + dops->set_device_resets = ti_sci_cmd_set_device_resets; + dops->get_device_resets = ti_sci_cmd_get_device_resets; } /** diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index 4377665d65..b4d58199e1 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -26,6 +26,11 @@ #define TI_SCI_MSG_BOARD_CONFIG_SECURITY 0x000d #define TI_SCI_MSG_BOARD_CONFIG_PM 0x000e +/* Device requests */ +#define TI_SCI_MSG_SET_DEVICE_STATE 0x0200 +#define TI_SCI_MSG_GET_DEVICE_STATE 0x0201 +#define TI_SCI_MSG_SET_DEVICE_RESETS 0x0202 + /** * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses * @type: Type of messages: One of TI_SCI_MSG* values @@ -98,4 +103,97 @@ struct ti_sci_msg_board_config { u16 boardcfg_size; } __packed; +/** + * struct ti_sci_msg_req_set_device_state - Set the desired state of the device + * @hdr: Generic header + * @id: Indicates which device to modify + * @reserved: Reserved space in message, must be 0 for backward compatibility + * @state: The desired state of the device. + * + * Certain flags can also be set to alter the device state: + * + MSG_FLAG_DEVICE_WAKE_ENABLED - Configure the device to be a wake source. + * The meaning of this flag will vary slightly from device to device and from + * SoC to SoC but it generally allows the device to wake the SoC out of deep + * suspend states. + * + MSG_FLAG_DEVICE_RESET_ISO - Enable reset isolation for this device. + * + MSG_FLAG_DEVICE_EXCLUSIVE - Claim this device exclusively. When passed + * with STATE_RETENTION or STATE_ON, it will claim the device exclusively. + * If another host already has this device set to STATE_RETENTION or STATE_ON, + * the message will fail. Once successful, other hosts attempting to set + * STATE_RETENTION or STATE_ON will fail. + * + * Request type is TI_SCI_MSG_SET_DEVICE_STATE, responded with a generic + * ACK/NACK message. + */ +struct ti_sci_msg_req_set_device_state { + /* Additional hdr->flags options */ +#define MSG_FLAG_DEVICE_WAKE_ENABLED TI_SCI_MSG_FLAG(8) +#define MSG_FLAG_DEVICE_RESET_ISO TI_SCI_MSG_FLAG(9) +#define MSG_FLAG_DEVICE_EXCLUSIVE TI_SCI_MSG_FLAG(10) + struct ti_sci_msg_hdr hdr; + u32 id; + u32 reserved; + +#define MSG_DEVICE_SW_STATE_AUTO_OFF 0 +#define MSG_DEVICE_SW_STATE_RETENTION 1 +#define MSG_DEVICE_SW_STATE_ON 2 + u8 state; +} __packed; + +/** + * struct ti_sci_msg_req_get_device_state - Request to get device. + * @hdr: Generic header + * @id: Device Identifier + * + * Request type is TI_SCI_MSG_GET_DEVICE_STATE, responded device state + * information + */ +struct ti_sci_msg_req_get_device_state { + struct ti_sci_msg_hdr hdr; + u32 id; +} __packed; + +/** + * struct ti_sci_msg_resp_get_device_state - Response to get device request. + * @hdr: Generic header + * @context_loss_count: Indicates how many times the device has lost context. A + * driver can use this monotonic counter to determine if the device has + * lost context since the last time this message was exchanged. + * @resets: Programmed state of the reset lines. + * @programmed_state: The state as programmed by set_device. + * - Uses the MSG_DEVICE_SW_* macros + * @current_state: The actual state of the hardware. + * + * Response to request TI_SCI_MSG_GET_DEVICE_STATE. + */ +struct ti_sci_msg_resp_get_device_state { + struct ti_sci_msg_hdr hdr; + u32 context_loss_count; + u32 resets; + u8 programmed_state; +#define MSG_DEVICE_HW_STATE_OFF 0 +#define MSG_DEVICE_HW_STATE_ON 1 +#define MSG_DEVICE_HW_STATE_TRANS 2 + u8 current_state; +} __packed; + +/** + * struct ti_sci_msg_req_set_device_resets - Set the desired resets + * configuration of the device + * @hdr: Generic header + * @id: Indicates which device to modify + * @resets: A bit field of resets for the device. The meaning, behavior, + * and usage of the reset flags are device specific. 0 for a bit + * indicates releasing the reset represented by that bit while 1 + * indicates keeping it held. + * + * Request type is TI_SCI_MSG_SET_DEVICE_RESETS, responded with a generic + * ACK/NACK message. + */ +struct ti_sci_msg_req_set_device_resets { + struct ti_sci_msg_hdr hdr; + u32 id; + u32 resets; +} __packed; + #endif /* __TI_SCI_H */ diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index 88b940fb8e..eabf77bf75 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -58,12 +58,93 @@ struct ti_sci_board_ops { u64 addr, u32 size); }; +/** + * struct ti_sci_dev_ops - Device control operations + * @get_device: Command to request for device managed by TISCI + * Returns 0 for successful exclusive request, else returns + * corresponding error message. + * @idle_device: Command to idle a device managed by TISCI + * Returns 0 for successful exclusive request, else returns + * corresponding error message. + * @put_device: Command to release a device managed by TISCI + * Returns 0 for successful release, else returns corresponding + * error message. + * @is_valid: Check if the device ID is a valid ID. + * Returns 0 if the ID is valid, else returns corresponding error. + * @get_context_loss_count: Command to retrieve context loss counter - this + * increments every time the device looses context. Overflow + * is possible. + * - count: pointer to u32 which will retrieve counter + * Returns 0 for successful information request and count has + * proper data, else returns corresponding error message. + * @is_idle: Reports back about device idle state + * - req_state: Returns requested idle state + * Returns 0 for successful information request and req_state and + * current_state has proper data, else returns corresponding error + * message. + * @is_stop: Reports back about device stop state + * - req_state: Returns requested stop state + * - current_state: Returns current stop state + * Returns 0 for successful information request and req_state and + * current_state has proper data, else returns corresponding error + * message. + * @is_on: Reports back about device ON(or active) state + * - req_state: Returns requested ON state + * - current_state: Returns current ON state + * Returns 0 for successful information request and req_state and + * current_state has proper data, else returns corresponding error + * message. + * @is_transitioning: Reports back if the device is in the middle of transition + * of state. + * -current_state: Returns 'true' if currently transitioning. + * @set_device_resets: Command to configure resets for device managed by TISCI. + * -reset_state: Device specific reset bit field + * Returns 0 for successful request, else returns + * corresponding error message. + * @get_device_resets: Command to read state of resets for device managed + * by TISCI. + * -reset_state: pointer to u32 which will retrieve resets + * Returns 0 for successful request, else returns + * corresponding error message. + * + * NOTE: for all these functions, the following parameters are generic in + * nature: + * -handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle + * -id: Device Identifier + * + * Request for the device - NOTE: the client MUST maintain integrity of + * usage count by balancing get_device with put_device. No refcounting is + * managed by driver for that purpose. + */ +struct ti_sci_dev_ops { + int (*get_device)(const struct ti_sci_handle *handle, u32 id); + int (*idle_device)(const struct ti_sci_handle *handle, u32 id); + int (*put_device)(const struct ti_sci_handle *handle, u32 id); + int (*is_valid)(const struct ti_sci_handle *handle, u32 id); + int (*get_context_loss_count)(const struct ti_sci_handle *handle, + u32 id, u32 *count); + int (*is_idle)(const struct ti_sci_handle *handle, u32 id, + bool *requested_state); + int (*is_stop)(const struct ti_sci_handle *handle, u32 id, + bool *req_state, bool *current_state); + int (*is_on)(const struct ti_sci_handle *handle, u32 id, + bool *req_state, bool *current_state); + int (*is_transitioning)(const struct ti_sci_handle *handle, u32 id, + bool *current_state); + int (*set_device_resets)(const struct ti_sci_handle *handle, u32 id, + u32 reset_state); + int (*get_device_resets)(const struct ti_sci_handle *handle, u32 id, + u32 *reset_state); +}; + /** * struct ti_sci_ops - Function support for TI SCI * @board_ops: Miscellaneous operations + * @dev_ops: Device specific operations */ struct ti_sci_ops { struct ti_sci_board_ops board_ops; + struct ti_sci_dev_ops dev_ops; }; /** From patchwork Tue Aug 21 14:31:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960420 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="gKk9LSXY"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtY463mvz9s4v for ; Wed, 22 Aug 2018 00:36:56 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 8A047C21E50; Tue, 21 Aug 2018 14:35:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id C3F53C21E0B; Tue, 21 Aug 2018 14:34:06 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 4A87BC21E2C; Tue, 21 Aug 2018 14:33:39 +0000 (UTC) Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) by lists.denx.de (Postfix) with ESMTPS id 592B4C21E18 for ; Tue, 21 Aug 2018 14:33:34 +0000 (UTC) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXWWv115880; Tue, 21 Aug 2018 09:33:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1534862012; bh=GH31ugfTRsH+I4I96IX8kINx+J7fMAbIkB9LDDTN5Ko=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=gKk9LSXYRvHkugRYNmGhlr4pYZXTi5mhENE2qrA/vUBTJayaV7Xbm3oCCAu0Hp/ZJ Gl1jDoFUiJIVlTu3HQCrGRS+zwwDApYqxxJPQePNnBZAQSUpJL3Q7xHrK9cC4Rs7wa mQH1nCcFFUQmKhKPGr1DEZfeBA1dAYRIrQ3nd0sY= Received: from DLEE105.ent.ti.com (dlee105.ent.ti.com [157.170.170.35]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXW8d010961; Tue, 21 Aug 2018 09:33:32 -0500 Received: from DLEE101.ent.ti.com (157.170.170.31) by DLEE105.ent.ti.com (157.170.170.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:32 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE101.ent.ti.com (157.170.170.31) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:32 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhP016556; Tue, 21 Aug 2018 09:33:30 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:42 +0530 Message-ID: <20180821143203.29142-5-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 04/25] firmware: ti_sci: Add support for clock control X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" In general, we expect to function at a device level of abstraction, however, for proper operation of hardware blocks, many clocks directly supplying the hardware block needs to be queried or configured. Introduce support for the set of SCI message protocol support that provide us with this capability. Signed-off-by: Lokesh Vutla Signed-off-by: Nishanth Menon Reviewed-by: Tom Rini --- drivers/firmware/ti_sci.c | 639 +++++++++++++++++++++++++ drivers/firmware/ti_sci.h | 289 +++++++++++ include/linux/soc/ti/ti_sci_protocol.h | 78 +++ 3 files changed, 1006 insertions(+) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index fc55b0f67a..af7c5c7ee9 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -774,6 +774,629 @@ static int ti_sci_cmd_get_device_resets(const struct ti_sci_handle *handle, NULL); } +/** + * ti_sci_set_clock_state() - Set clock state helper + * @handle: pointer to TI SCI handle + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @flags: Header flags as needed + * @state: State to request for the clock. + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_set_clock_state(const struct ti_sci_handle *handle, + u32 dev_id, u8 clk_id, + u32 flags, u8 state) +{ + struct ti_sci_msg_req_set_clock_state req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_CLOCK_STATE, + flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.dev_id = dev_id; + req.clk_id = clk_id; + req.request_state = state; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + return -ENODEV; + + return ret; +} + +/** + * ti_sci_cmd_get_clock_state() - Get clock state helper + * @handle: pointer to TI SCI handle + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @programmed_state: State requested for clock to move to + * @current_state: State that the clock is currently in + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle, + u32 dev_id, u8 clk_id, + u8 *programmed_state, u8 *current_state) +{ + struct ti_sci_msg_resp_get_clock_state *resp; + struct ti_sci_msg_req_get_clock_state req; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + if (!programmed_state && !current_state) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_CLOCK_STATE, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.dev_id = dev_id; + req.clk_id = clk_id; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_resp_get_clock_state *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + return -ENODEV; + + if (programmed_state) + *programmed_state = resp->programmed_state; + if (current_state) + *current_state = resp->current_state; + + return ret; +} + +/** + * ti_sci_cmd_get_clock() - Get control of a clock from TI SCI + * @handle: pointer to TI SCI handle + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @needs_ssc: 'true' if Spread Spectrum clock is desired, else 'false' + * @can_change_freq: 'true' if frequency change is desired, else 'false' + * @enable_input_term: 'true' if input termination is desired, else 'false' + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_get_clock(const struct ti_sci_handle *handle, u32 dev_id, + u8 clk_id, bool needs_ssc, bool can_change_freq, + bool enable_input_term) +{ + u32 flags = 0; + + flags |= needs_ssc ? MSG_FLAG_CLOCK_ALLOW_SSC : 0; + flags |= can_change_freq ? MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE : 0; + flags |= enable_input_term ? MSG_FLAG_CLOCK_INPUT_TERM : 0; + + return ti_sci_set_clock_state(handle, dev_id, clk_id, flags, + MSG_CLOCK_SW_STATE_REQ); +} + +/** + * ti_sci_cmd_idle_clock() - Idle a clock which is in our control + * @handle: pointer to TI SCI handle + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * + * NOTE: This clock must have been requested by get_clock previously. + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_idle_clock(const struct ti_sci_handle *handle, + u32 dev_id, u8 clk_id) +{ + return ti_sci_set_clock_state(handle, dev_id, clk_id, 0, + MSG_CLOCK_SW_STATE_UNREQ); +} + +/** + * ti_sci_cmd_put_clock() - Release a clock from our control back to TISCI + * @handle: pointer to TI SCI handle + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * + * NOTE: This clock must have been requested by get_clock previously. + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_put_clock(const struct ti_sci_handle *handle, + u32 dev_id, u8 clk_id) +{ + return ti_sci_set_clock_state(handle, dev_id, clk_id, 0, + MSG_CLOCK_SW_STATE_AUTO); +} + +/** + * ti_sci_cmd_clk_is_auto() - Is the clock being auto managed + * @handle: pointer to TI SCI handle + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @req_state: state indicating if the clock is auto managed + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_clk_is_auto(const struct ti_sci_handle *handle, + u32 dev_id, u8 clk_id, bool *req_state) +{ + u8 state = 0; + int ret; + + if (!req_state) + return -EINVAL; + + ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, &state, NULL); + if (ret) + return ret; + + *req_state = (state == MSG_CLOCK_SW_STATE_AUTO); + return 0; +} + +/** + * ti_sci_cmd_clk_is_on() - Is the clock ON + * @handle: pointer to TI SCI handle + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @req_state: state indicating if the clock is managed by us and enabled + * @curr_state: state indicating if the clock is ready for operation + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_clk_is_on(const struct ti_sci_handle *handle, u32 dev_id, + u8 clk_id, bool *req_state, bool *curr_state) +{ + u8 c_state = 0, r_state = 0; + int ret; + + if (!req_state && !curr_state) + return -EINVAL; + + ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, + &r_state, &c_state); + if (ret) + return ret; + + if (req_state) + *req_state = (r_state == MSG_CLOCK_SW_STATE_REQ); + if (curr_state) + *curr_state = (c_state == MSG_CLOCK_HW_STATE_READY); + return 0; +} + +/** + * ti_sci_cmd_clk_is_off() - Is the clock OFF + * @handle: pointer to TI SCI handle + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @req_state: state indicating if the clock is managed by us and disabled + * @curr_state: state indicating if the clock is NOT ready for operation + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_clk_is_off(const struct ti_sci_handle *handle, u32 dev_id, + u8 clk_id, bool *req_state, bool *curr_state) +{ + u8 c_state = 0, r_state = 0; + int ret; + + if (!req_state && !curr_state) + return -EINVAL; + + ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, + &r_state, &c_state); + if (ret) + return ret; + + if (req_state) + *req_state = (r_state == MSG_CLOCK_SW_STATE_UNREQ); + if (curr_state) + *curr_state = (c_state == MSG_CLOCK_HW_STATE_NOT_READY); + return 0; +} + +/** + * ti_sci_cmd_clk_set_parent() - Set the clock source of a specific device clock + * @handle: pointer to TI SCI handle + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @parent_id: Parent clock identifier to set + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle, + u32 dev_id, u8 clk_id, u8 parent_id) +{ + struct ti_sci_msg_req_set_clock_parent req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_CLOCK_PARENT, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.dev_id = dev_id; + req.clk_id = clk_id; + req.parent_id = parent_id; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + return -ENODEV; + + return ret; +} + +/** + * ti_sci_cmd_clk_get_parent() - Get current parent clock source + * @handle: pointer to TI SCI handle + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @parent_id: Current clock parent + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle, + u32 dev_id, u8 clk_id, u8 *parent_id) +{ + struct ti_sci_msg_resp_get_clock_parent *resp; + struct ti_sci_msg_req_get_clock_parent req; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle || !parent_id) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_CLOCK_PARENT, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.dev_id = dev_id; + req.clk_id = clk_id; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + ret = -ENODEV; + else + *parent_id = resp->parent_id; + + return ret; +} + +/** + * ti_sci_cmd_clk_get_num_parents() - Get num parents of the current clk source + * @handle: pointer to TI SCI handle + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @num_parents: Returns he number of parents to the current clock. + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle, + u32 dev_id, u8 clk_id, + u8 *num_parents) +{ + struct ti_sci_msg_resp_get_clock_num_parents *resp; + struct ti_sci_msg_req_get_clock_num_parents req; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle || !num_parents) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_NUM_CLOCK_PARENTS, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.dev_id = dev_id; + req.clk_id = clk_id; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_resp_get_clock_num_parents *) + xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + ret = -ENODEV; + else + *num_parents = resp->num_parents; + + return ret; +} + +/** + * ti_sci_cmd_clk_get_match_freq() - Find a good match for frequency + * @handle: pointer to TI SCI handle + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @min_freq: The minimum allowable frequency in Hz. This is the minimum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @target_freq: The target clock frequency in Hz. A frequency will be + * processed as close to this target frequency as possible. + * @max_freq: The maximum allowable frequency in Hz. This is the maximum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @match_freq: Frequency match in Hz response. + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle, + u32 dev_id, u8 clk_id, u64 min_freq, + u64 target_freq, u64 max_freq, + u64 *match_freq) +{ + struct ti_sci_msg_resp_query_clock_freq *resp; + struct ti_sci_msg_req_query_clock_freq req; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle || !match_freq) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_QUERY_CLOCK_FREQ, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.dev_id = dev_id; + req.clk_id = clk_id; + req.min_freq_hz = min_freq; + req.target_freq_hz = target_freq; + req.max_freq_hz = max_freq; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_resp_query_clock_freq *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + ret = -ENODEV; + else + *match_freq = resp->freq_hz; + + return ret; +} + +/** + * ti_sci_cmd_clk_set_freq() - Set a frequency for clock + * @handle: pointer to TI SCI handle + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @min_freq: The minimum allowable frequency in Hz. This is the minimum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @target_freq: The target clock frequency in Hz. A frequency will be + * processed as close to this target frequency as possible. + * @max_freq: The maximum allowable frequency in Hz. This is the maximum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle, + u32 dev_id, u8 clk_id, u64 min_freq, + u64 target_freq, u64 max_freq) +{ + struct ti_sci_msg_req_set_clock_freq req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_CLOCK_FREQ, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.dev_id = dev_id; + req.clk_id = clk_id; + req.min_freq_hz = min_freq; + req.target_freq_hz = target_freq; + req.max_freq_hz = max_freq; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + return -ENODEV; + + return ret; +} + +/** + * ti_sci_cmd_clk_get_freq() - Get current frequency + * @handle: pointer to TI SCI handle + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @freq: Currently frequency in Hz + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle, + u32 dev_id, u8 clk_id, u64 *freq) +{ + struct ti_sci_msg_resp_get_clock_freq *resp; + struct ti_sci_msg_req_get_clock_freq req; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle || !freq) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_CLOCK_FREQ, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.dev_id = dev_id; + req.clk_id = clk_id; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_resp_get_clock_freq *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + ret = -ENODEV; + else + *freq = resp->freq_hz; + + return ret; +} + /* * ti_sci_setup_ops() - Setup the operations structures * @info: pointer to TISCI pointer @@ -783,6 +1406,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) struct ti_sci_ops *ops = &info->handle.ops; struct ti_sci_board_ops *bops = &ops->board_ops; struct ti_sci_dev_ops *dops = &ops->dev_ops; + struct ti_sci_clk_ops *cops = &ops->clk_ops; bops->board_config = ti_sci_cmd_set_board_config; bops->board_config_rm = ti_sci_cmd_set_board_config_rm; @@ -800,6 +1424,21 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) dops->is_transitioning = ti_sci_cmd_dev_is_trans; dops->set_device_resets = ti_sci_cmd_set_device_resets; dops->get_device_resets = ti_sci_cmd_get_device_resets; + + cops->get_clock = ti_sci_cmd_get_clock; + cops->idle_clock = ti_sci_cmd_idle_clock; + cops->put_clock = ti_sci_cmd_put_clock; + cops->is_auto = ti_sci_cmd_clk_is_auto; + cops->is_on = ti_sci_cmd_clk_is_on; + cops->is_off = ti_sci_cmd_clk_is_off; + + cops->set_parent = ti_sci_cmd_clk_set_parent; + cops->get_parent = ti_sci_cmd_clk_get_parent; + cops->get_num_parents = ti_sci_cmd_clk_get_num_parents; + + cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq; + cops->set_freq = ti_sci_cmd_clk_set_freq; + cops->get_freq = ti_sci_cmd_clk_get_freq; } /** diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index b4d58199e1..7b7c7e7530 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -31,6 +31,16 @@ #define TI_SCI_MSG_GET_DEVICE_STATE 0x0201 #define TI_SCI_MSG_SET_DEVICE_RESETS 0x0202 +/* Clock requests */ +#define TI_SCI_MSG_SET_CLOCK_STATE 0x0100 +#define TI_SCI_MSG_GET_CLOCK_STATE 0x0101 +#define TI_SCI_MSG_SET_CLOCK_PARENT 0x0102 +#define TI_SCI_MSG_GET_CLOCK_PARENT 0x0103 +#define TI_SCI_MSG_GET_NUM_CLOCK_PARENTS 0x0104 +#define TI_SCI_MSG_SET_CLOCK_FREQ 0x010c +#define TI_SCI_MSG_QUERY_CLOCK_FREQ 0x010d +#define TI_SCI_MSG_GET_CLOCK_FREQ 0x010e + /** * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses * @type: Type of messages: One of TI_SCI_MSG* values @@ -196,4 +206,283 @@ struct ti_sci_msg_req_set_device_resets { u32 resets; } __packed; +/** + * struct ti_sci_msg_req_set_clock_state - Request to setup a Clock state + * @hdr: Generic Header, Certain flags can be set specific to the clocks: + * MSG_FLAG_CLOCK_ALLOW_SSC: Allow this clock to be modified + * via spread spectrum clocking. + * MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE: Allow this clock's + * frequency to be changed while it is running so long as it + * is within the min/max limits. + * MSG_FLAG_CLOCK_INPUT_TERM: Enable input termination, this + * is only applicable to clock inputs on the SoC pseudo-device. + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @request_state: Request the state for the clock to be set to. + * MSG_CLOCK_SW_STATE_UNREQ: The IP does not require this clock, + * it can be disabled, regardless of the state of the device + * MSG_CLOCK_SW_STATE_AUTO: Allow the System Controller to + * automatically manage the state of this clock. If the device + * is enabled, then the clock is enabled. If the device is set + * to off or retention, then the clock is internally set as not + * being required by the device.(default) + * MSG_CLOCK_SW_STATE_REQ: Configure the clock to be enabled, + * regardless of the state of the device. + * + * Normally, all required clocks are managed by TISCI entity, this is used + * only for specific control *IF* required. Auto managed state is + * MSG_CLOCK_SW_STATE_AUTO, in other states, TISCI entity assume remote + * will explicitly control. + * + * Request type is TI_SCI_MSG_SET_CLOCK_STATE, response is a generic + * ACK or NACK message. + */ +struct ti_sci_msg_req_set_clock_state { + /* Additional hdr->flags options */ +#define MSG_FLAG_CLOCK_ALLOW_SSC TI_SCI_MSG_FLAG(8) +#define MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE TI_SCI_MSG_FLAG(9) +#define MSG_FLAG_CLOCK_INPUT_TERM TI_SCI_MSG_FLAG(10) + struct ti_sci_msg_hdr hdr; + u32 dev_id; + u8 clk_id; +#define MSG_CLOCK_SW_STATE_UNREQ 0 +#define MSG_CLOCK_SW_STATE_AUTO 1 +#define MSG_CLOCK_SW_STATE_REQ 2 + u8 request_state; +} __packed; + +/** + * struct ti_sci_msg_req_get_clock_state - Request for clock state + * @hdr: Generic Header + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to get state of. + * + * Request type is TI_SCI_MSG_GET_CLOCK_STATE, response is state + * of the clock + */ +struct ti_sci_msg_req_get_clock_state { + struct ti_sci_msg_hdr hdr; + u32 dev_id; + u8 clk_id; +} __packed; + +/** + * struct ti_sci_msg_resp_get_clock_state - Response to get clock state + * @hdr: Generic Header + * @programmed_state: Any programmed state of the clock. This is one of + * MSG_CLOCK_SW_STATE* values. + * @current_state: Current state of the clock. This is one of: + * MSG_CLOCK_HW_STATE_NOT_READY: Clock is not ready + * MSG_CLOCK_HW_STATE_READY: Clock is ready + * + * Response to TI_SCI_MSG_GET_CLOCK_STATE. + */ +struct ti_sci_msg_resp_get_clock_state { + struct ti_sci_msg_hdr hdr; + u8 programmed_state; +#define MSG_CLOCK_HW_STATE_NOT_READY 0 +#define MSG_CLOCK_HW_STATE_READY 1 + u8 current_state; +} __packed; + +/** + * struct ti_sci_msg_req_set_clock_parent - Set the clock parent + * @hdr: Generic Header + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @parent_id: The new clock parent is selectable by an index via this + * parameter. + * + * Request type is TI_SCI_MSG_SET_CLOCK_PARENT, response is generic + * ACK / NACK message. + */ +struct ti_sci_msg_req_set_clock_parent { + struct ti_sci_msg_hdr hdr; + u32 dev_id; + u8 clk_id; + u8 parent_id; +} __packed; + +/** + * struct ti_sci_msg_req_get_clock_parent - Get the clock parent + * @hdr: Generic Header + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to get the parent for. + * + * Request type is TI_SCI_MSG_GET_CLOCK_PARENT, response is parent information + */ +struct ti_sci_msg_req_get_clock_parent { + struct ti_sci_msg_hdr hdr; + u32 dev_id; + u8 clk_id; +} __packed; + +/** + * struct ti_sci_msg_resp_get_clock_parent - Response with clock parent + * @hdr: Generic Header + * @parent_id: The current clock parent + * + * Response to TI_SCI_MSG_GET_CLOCK_PARENT. + */ +struct ti_sci_msg_resp_get_clock_parent { + struct ti_sci_msg_hdr hdr; + u8 parent_id; +} __packed; + +/** + * struct ti_sci_msg_req_get_clock_num_parents - Request to get clock parents + * @hdr: Generic header + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * + * This request provides information about how many clock parent options + * are available for a given clock to a device. This is typically used + * for input clocks. + * + * Request type is TI_SCI_MSG_GET_NUM_CLOCK_PARENTS, response is appropriate + * message, or NACK in case of inability to satisfy request. + */ +struct ti_sci_msg_req_get_clock_num_parents { + struct ti_sci_msg_hdr hdr; + u32 dev_id; + u8 clk_id; +} __packed; + +/** + * struct ti_sci_msg_resp_get_clock_num_parents - Response for get clk parents + * @hdr: Generic header + * @num_parents: Number of clock parents + * + * Response to TI_SCI_MSG_GET_NUM_CLOCK_PARENTS + */ +struct ti_sci_msg_resp_get_clock_num_parents { + struct ti_sci_msg_hdr hdr; + u8 num_parents; +} __packed; + +/** + * struct ti_sci_msg_req_query_clock_freq - Request to query a frequency + * @hdr: Generic Header + * @dev_id: Device identifier this request is for + * @min_freq_hz: The minimum allowable frequency in Hz. This is the minimum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @target_freq_hz: The target clock frequency. A frequency will be found + * as close to this target frequency as possible. + * @max_freq_hz: The maximum allowable frequency in Hz. This is the maximum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @clk_id: Clock identifier for the device for this request. + * + * NOTE: Normally clock frequency management is automatically done by TISCI + * entity. In case of specific requests, TISCI evaluates capability to achieve + * requested frequency within provided range and responds with + * result message. + * + * Request type is TI_SCI_MSG_QUERY_CLOCK_FREQ, response is appropriate message, + * or NACK in case of inability to satisfy request. + */ +struct ti_sci_msg_req_query_clock_freq { + struct ti_sci_msg_hdr hdr; + u32 dev_id; + u64 min_freq_hz; + u64 target_freq_hz; + u64 max_freq_hz; + u8 clk_id; +} __packed; + +/** + * struct ti_sci_msg_resp_query_clock_freq - Response to a clock frequency query + * @hdr: Generic Header + * @freq_hz: Frequency that is the best match in Hz. + * + * Response to request type TI_SCI_MSG_QUERY_CLOCK_FREQ. NOTE: if the request + * cannot be satisfied, the message will be of type NACK. + */ +struct ti_sci_msg_resp_query_clock_freq { + struct ti_sci_msg_hdr hdr; + u64 freq_hz; +} __packed; + +/** + * struct ti_sci_msg_req_set_clock_freq - Request to setup a clock frequency + * @hdr: Generic Header + * @dev_id: Device identifier this request is for + * @min_freq_hz: The minimum allowable frequency in Hz. This is the minimum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @target_freq_hz: The target clock frequency. The clock will be programmed + * at a rate as close to this target frequency as possible. + * @max_freq_hz: The maximum allowable frequency in Hz. This is the maximum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @clk_id: Clock identifier for the device for this request. + * + * NOTE: Normally clock frequency management is automatically done by TISCI + * entity. In case of specific requests, TISCI evaluates capability to achieve + * requested range and responds with success/failure message. + * + * This sets the desired frequency for a clock within an allowable + * range. This message will fail on an enabled clock unless + * MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE is set for the clock. Additionally, + * if other clocks have their frequency modified due to this message, + * they also must have the MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE or be disabled. + * + * Calling set frequency on a clock input to the SoC pseudo-device will + * inform the PMMC of that clock's frequency. Setting a frequency of + * zero will indicate the clock is disabled. + * + * Calling set frequency on clock outputs from the SoC pseudo-device will + * function similarly to setting the clock frequency on a device. + * + * Request type is TI_SCI_MSG_SET_CLOCK_FREQ, response is a generic ACK/NACK + * message. + */ +struct ti_sci_msg_req_set_clock_freq { + struct ti_sci_msg_hdr hdr; + u32 dev_id; + u64 min_freq_hz; + u64 target_freq_hz; + u64 max_freq_hz; + u8 clk_id; +} __packed; + +/** + * struct ti_sci_msg_req_get_clock_freq - Request to get the clock frequency + * @hdr: Generic Header + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * + * NOTE: Normally clock frequency management is automatically done by TISCI + * entity. In some cases, clock frequencies are configured by host. + * + * Request type is TI_SCI_MSG_GET_CLOCK_FREQ, responded with clock frequency + * that the clock is currently at. + */ +struct ti_sci_msg_req_get_clock_freq { + struct ti_sci_msg_hdr hdr; + u32 dev_id; + u8 clk_id; +} __packed; + +/** + * struct ti_sci_msg_resp_get_clock_freq - Response of clock frequency request + * @hdr: Generic Header + * @freq_hz: Frequency that the clock is currently on, in Hz. + * + * Response to request type TI_SCI_MSG_GET_CLOCK_FREQ. + */ +struct ti_sci_msg_resp_get_clock_freq { + struct ti_sci_msg_hdr hdr; + u64 freq_hz; +} __packed; + #endif /* __TI_SCI_H */ diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index eabf77bf75..cec1c1a2bd 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -137,14 +137,92 @@ struct ti_sci_dev_ops { u32 *reset_state); }; +/** + * struct ti_sci_clk_ops - Clock control operations + * @get_clock: Request for activation of clock and manage by processor + * - needs_ssc: 'true' if Spread Spectrum clock is desired. + * - can_change_freq: 'true' if frequency change is desired. + * - enable_input_term: 'true' if input termination is desired. + * @idle_clock: Request for Idling a clock managed by processor + * @put_clock: Release the clock to be auto managed by TISCI + * @is_auto: Is the clock being auto managed + * - req_state: state indicating if the clock is auto managed + * @is_on: Is the clock ON + * - req_state: if the clock is requested to be forced ON + * - current_state: if the clock is currently ON + * @is_off: Is the clock OFF + * - req_state: if the clock is requested to be forced OFF + * - current_state: if the clock is currently Gated + * @set_parent: Set the clock source of a specific device clock + * - parent_id: Parent clock identifier to set. + * @get_parent: Get the current clock source of a specific device clock + * - parent_id: Parent clock identifier which is the parent. + * @get_num_parents: Get the number of parents of the current clock source + * - num_parents: returns the number of parent clocks. + * @get_best_match_freq: Find a best matching frequency for a frequency + * range. + * - match_freq: Best matching frequency in Hz. + * @set_freq: Set the Clock frequency + * @get_freq: Get the Clock frequency + * - current_freq: Frequency in Hz that the clock is at. + * + * NOTE: for all these functions, the following parameters are generic in + * nature: + * -handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle + * -did: Device identifier this request is for + * -cid: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * -min_freq: The minimum allowable frequency in Hz. This is the minimum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * -target_freq: The target clock frequency in Hz. A frequency will be + * processed as close to this target frequency as possible. + * -max_freq: The maximum allowable frequency in Hz. This is the maximum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * + * Request for the clock - NOTE: the client MUST maintain integrity of + * usage count by balancing get_clock with put_clock. No refcounting is + * managed by driver for that purpose. + */ +struct ti_sci_clk_ops { + int (*get_clock)(const struct ti_sci_handle *handle, u32 did, u8 cid, + bool needs_ssc, bool can_change_freq, + bool enable_input_term); + int (*idle_clock)(const struct ti_sci_handle *handle, u32 did, u8 cid); + int (*put_clock)(const struct ti_sci_handle *handle, u32 did, u8 cid); + int (*is_auto)(const struct ti_sci_handle *handle, u32 did, u8 cid, + bool *req_state); + int (*is_on)(const struct ti_sci_handle *handle, u32 did, u8 cid, + bool *req_state, bool *current_state); + int (*is_off)(const struct ti_sci_handle *handle, u32 did, u8 cid, + bool *req_state, bool *current_state); + int (*set_parent)(const struct ti_sci_handle *handle, u32 did, u8 cid, + u8 parent_id); + int (*get_parent)(const struct ti_sci_handle *handle, u32 did, u8 cid, + u8 *parent_id); + int (*get_num_parents)(const struct ti_sci_handle *handle, u32 did, + u8 cid, u8 *num_parents); + int (*get_best_match_freq)(const struct ti_sci_handle *handle, u32 did, + u8 cid, u64 min_freq, u64 target_freq, + u64 max_freq, u64 *match_freq); + int (*set_freq)(const struct ti_sci_handle *handle, u32 did, u8 cid, + u64 min_freq, u64 target_freq, u64 max_freq); + int (*get_freq)(const struct ti_sci_handle *handle, u32 did, u8 cid, + u64 *current_freq); +}; + /** * struct ti_sci_ops - Function support for TI SCI * @board_ops: Miscellaneous operations * @dev_ops: Device specific operations + * @clk_ops: Clock specific operations */ struct ti_sci_ops { struct ti_sci_board_ops board_ops; struct ti_sci_dev_ops dev_ops; + struct ti_sci_clk_ops clk_ops; }; /** From patchwork Tue Aug 21 14:31:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960438 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vthD2qRCz9s7X for ; Wed, 22 Aug 2018 00:43:08 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 10228C21E6C; Tue, 21 Aug 2018 14:37:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 3431FC21E60; Tue, 21 Aug 2018 14:34:15 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 2B407C21E60; Tue, 21 Aug 2018 14:33:41 +0000 (UTC) Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) by lists.denx.de (Postfix) with ESMTPS id BBBF0C21E15 for ; Tue, 21 Aug 2018 14:33:36 +0000 (UTC) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXZjY104671; Tue, 21 Aug 2018 09:33:35 -0500 Received: from DLEE107.ent.ti.com (dlee107.ent.ti.com [157.170.170.37]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXZef011005; Tue, 21 Aug 2018 09:33:35 -0500 Received: from DLEE108.ent.ti.com (157.170.170.38) by DLEE107.ent.ti.com (157.170.170.37) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:34 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE108.ent.ti.com (157.170.170.38) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:34 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhQ016556; Tue, 21 Aug 2018 09:33:32 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:43 +0530 Message-ID: <20180821143203.29142-6-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 05/25] firmware: ti_sci: Add support for reboot core service X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Andreas Dannenberg Since system controller now has control over SoC power management, it needs to be explicitly requested to reboot the SoC. Add support for it. Signed-off-by: Lokesh Vutla Signed-off-by: Nishanth Menon Reviewed-by: Tom Rini --- drivers/firmware/ti_sci.c | 47 ++++++++++++++++++++++++++ drivers/firmware/ti_sci.h | 11 ++++++ include/linux/soc/ti/ti_sci_protocol.h | 12 +++++++ 3 files changed, 70 insertions(+) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index af7c5c7ee9..e04bae2ef4 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -1397,6 +1397,50 @@ static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle, return ret; } +/** + * ti_sci_cmd_core_reboot() - Command to request system reset + * @handle: pointer to TI SCI handle + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle) +{ + struct ti_sci_msg_req_reboot req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SYS_RESET, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + return -ENODEV; + + return ret; +} + /* * ti_sci_setup_ops() - Setup the operations structures * @info: pointer to TISCI pointer @@ -1407,6 +1451,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) struct ti_sci_board_ops *bops = &ops->board_ops; struct ti_sci_dev_ops *dops = &ops->dev_ops; struct ti_sci_clk_ops *cops = &ops->clk_ops; + struct ti_sci_core_ops *core_ops = &ops->core_ops; bops->board_config = ti_sci_cmd_set_board_config; bops->board_config_rm = ti_sci_cmd_set_board_config_rm; @@ -1439,6 +1484,8 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq; cops->set_freq = ti_sci_cmd_clk_set_freq; cops->get_freq = ti_sci_cmd_clk_get_freq; + + core_ops->reboot_device = ti_sci_cmd_core_reboot; } /** diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index 7b7c7e7530..714a066985 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -95,6 +95,17 @@ struct ti_sci_msg_resp_version { u8 abi_minor; } __packed; +/** + * struct ti_sci_msg_req_reboot - Reboot the SoC + * @hdr: Generic Header + * + * Request type is TI_SCI_MSG_SYS_RESET, responded with a generic + * ACK/NACK message. + */ +struct ti_sci_msg_req_reboot { + struct ti_sci_msg_hdr hdr; +} __packed; + /** * struct ti_sci_msg_board_config - Board configuration message * @hdr: Generic Header diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index cec1c1a2bd..e3ce993fa3 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -213,16 +213,28 @@ struct ti_sci_clk_ops { u64 *current_freq); }; +/** + * struct ti_sci_core_ops - SoC Core Operations + * @reboot_device: Reboot the SoC + * Returns 0 for successful request(ideally should never return), + * else returns corresponding error value. + */ +struct ti_sci_core_ops { + int (*reboot_device)(const struct ti_sci_handle *handle); +}; + /** * struct ti_sci_ops - Function support for TI SCI * @board_ops: Miscellaneous operations * @dev_ops: Device specific operations * @clk_ops: Clock specific operations + * @core_ops: Core specific operations */ struct ti_sci_ops { struct ti_sci_board_ops board_ops; struct ti_sci_dev_ops dev_ops; struct ti_sci_clk_ops clk_ops; + struct ti_sci_core_ops core_ops; }; /** From patchwork Tue Aug 21 14:31:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960460 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="ydhDGJWu"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtsP5gPTz9sBW for ; Wed, 22 Aug 2018 00:51:05 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 165ADC21DF3; Tue, 21 Aug 2018 14:37:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 0077AC21E56; Tue, 21 Aug 2018 14:34:18 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 0F1ECC21E2F; Tue, 21 Aug 2018 14:33:42 +0000 (UTC) Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) by lists.denx.de (Postfix) with ESMTPS id BFC59C21E3A for ; Tue, 21 Aug 2018 14:33:38 +0000 (UTC) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXbiY115900; Tue, 21 Aug 2018 09:33:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1534862017; bh=UJbLvvzK1SyD99OBZjKSAqEkPYkpyMeLZB/ajVypzgg=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=ydhDGJWuzSXfxNvbk8pCN+W89gEFpR4AG4OYUT+s8FFOXFBEtNbOtQQ0wiWpNqsLH JqT7IvxHbI7KwSMlYlZuhxBoQz0064kHxiPi+8Lf4PQA7Yk6EX/IYlUrNpszg/q3R0 bMxWTQoNl9wH3UykYrhGWlJ1Js5cDQRqzMHHsJ1o= Received: from DLEE102.ent.ti.com (dlee102.ent.ti.com [157.170.170.32]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXbNQ011027; Tue, 21 Aug 2018 09:33:37 -0500 Received: from DLEE102.ent.ti.com (157.170.170.32) by DLEE102.ent.ti.com (157.170.170.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:36 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE102.ent.ti.com (157.170.170.32) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:36 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhR016556; Tue, 21 Aug 2018 09:33:35 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:44 +0530 Message-ID: <20180821143203.29142-7-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 06/25] firmware: ti_sci: Add support for processor control services X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" TI-SCI message protocol provides support for controlling of various physical cores available in SoC. In order to control which host is capable of controlling a physical processor core, there is a processor access control list that needs to be populated as part of the board configuration data. Introduce support for the set of TI-SCI message protocol apis that provide us with this capability of controlling physical cores. ToDo: - Create separate TISCI commands for control, config, status flags. - Update Documentation. Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- drivers/firmware/ti_sci.c | 371 +++++++++++++++++++++++++ drivers/firmware/ti_sci.h | 181 ++++++++++++ include/linux/soc/ti/ti_sci_protocol.h | 37 +++ 3 files changed, 589 insertions(+) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index e04bae2ef4..32d69dab2f 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -1441,6 +1441,368 @@ static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle) return ret; } +/** + * ti_sci_cmd_proc_request() - Command to request a physical processor control + * @handle: Pointer to TI SCI handle + * @proc_id: Processor ID this request is for + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle, + u8 proc_id) +{ + struct ti_sci_msg_req_proc_request req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_REQUEST, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.processor_id = proc_id; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + ret = -ENODEV; + + return ret; +} + +/** + * ti_sci_cmd_proc_release() - Command to release a physical processor control + * @handle: Pointer to TI SCI handle + * @proc_id: Processor ID this request is for + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle, + u8 proc_id) +{ + struct ti_sci_msg_req_proc_release req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_RELEASE, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.processor_id = proc_id; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + ret = -ENODEV; + + return ret; +} + +/** + * ti_sci_cmd_proc_handover() - Command to handover a physical processor + * control to a host in the processor's access + * control list. + * @handle: Pointer to TI SCI handle + * @proc_id: Processor ID this request is for + * @host_id: Host ID to get the control of the processor + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle, + u8 proc_id, u8 host_id) +{ + struct ti_sci_msg_req_proc_handover req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_HANDOVER, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.processor_id = proc_id; + req.host_id = host_id; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + ret = -ENODEV; + + return ret; +} + +/** + * ti_sci_cmd_set_proc_boot_cfg() - Command to set the processor boot + * configuration flags + * @handle: Pointer to TI SCI handle + * @proc_id: Processor ID this request is for + * @config_flags_set: Configuration flags to be set + * @config_flags_clear: Configuration flags to be cleared. + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_set_proc_boot_cfg(const struct ti_sci_handle *handle, + u8 proc_id, u64 bootvector, + u32 config_flags_set, + u32 config_flags_clear) +{ + struct ti_sci_msg_req_set_proc_boot_config req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_SET_PROC_BOOT_CONFIG, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.processor_id = proc_id; + req.bootvector_low = bootvector & TISCI_ADDR_LOW_MASK; + req.bootvector_high = (bootvector & TISCI_ADDR_HIGH_MASK) >> + TISCI_ADDR_HIGH_SHIFT; + req.config_flags_set = config_flags_set; + req.config_flags_clear = config_flags_clear; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + ret = -ENODEV; + + return ret; +} + +/** + * ti_sci_cmd_set_proc_boot_ctrl() - Command to set the processor boot + * control flags + * @handle: Pointer to TI SCI handle + * @proc_id: Processor ID this request is for + * @control_flags_set: Control flags to be set + * @control_flags_clear: Control flags to be cleared + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle *handle, + u8 proc_id, u32 control_flags_set, + u32 control_flags_clear) +{ + struct ti_sci_msg_req_set_proc_boot_ctrl req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_SET_PROC_BOOT_CTRL, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.processor_id = proc_id; + req.control_flags_set = control_flags_set; + req.control_flags_clear = control_flags_clear; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + ret = -ENODEV; + + return ret; +} + +/** + * ti_sci_cmd_proc_auth_boot_image() - Command to authenticate and load the + * image and then set the processor configuration flags. + * @handle: Pointer to TI SCI handle + * @proc_id: Processor ID this request is for + * @cert_addr: Memory address at which payload image certificate is located. + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle, + u8 proc_id, u64 cert_addr) +{ + struct ti_sci_msg_req_proc_auth_boot_image req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_AUTH_BOOT_IMIAGE, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.processor_id = proc_id; + req.cert_addr_low = cert_addr & TISCI_ADDR_LOW_MASK; + req.cert_addr_high = (cert_addr & TISCI_ADDR_HIGH_MASK) >> + TISCI_ADDR_HIGH_SHIFT; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + ret = -ENODEV; + + return ret; +} + +/** + * ti_sci_cmd_get_proc_boot_status() - Command to get the processor boot status + * @handle: Pointer to TI SCI handle + * @proc_id: Processor ID this request is for + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_get_proc_boot_status(const struct ti_sci_handle *handle, + u8 proc_id, u64 *bv, u32 *cfg_flags, + u32 *ctrl_flags, u32 *sts_flags) +{ + struct ti_sci_msg_resp_get_proc_boot_status *resp; + struct ti_sci_msg_req_get_proc_boot_status req; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_GET_PROC_BOOT_STATUS, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.processor_id = proc_id; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_resp_get_proc_boot_status *) + xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + return -ENODEV; + *bv = (resp->bootvector_low & TISCI_ADDR_LOW_MASK) | + (((u64)resp->bootvector_high << + TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK); + *cfg_flags = resp->config_flags; + *ctrl_flags = resp->control_flags; + *sts_flags = resp->status_flags; + + return ret; +} + /* * ti_sci_setup_ops() - Setup the operations structures * @info: pointer to TISCI pointer @@ -1452,6 +1814,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) struct ti_sci_dev_ops *dops = &ops->dev_ops; struct ti_sci_clk_ops *cops = &ops->clk_ops; struct ti_sci_core_ops *core_ops = &ops->core_ops; + struct ti_sci_proc_ops *pops = &ops->proc_ops; bops->board_config = ti_sci_cmd_set_board_config; bops->board_config_rm = ti_sci_cmd_set_board_config_rm; @@ -1486,6 +1849,14 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) cops->get_freq = ti_sci_cmd_clk_get_freq; core_ops->reboot_device = ti_sci_cmd_core_reboot; + + pops->proc_request = ti_sci_cmd_proc_request; + pops->proc_release = ti_sci_cmd_proc_release; + pops->proc_handover = ti_sci_cmd_proc_handover; + pops->set_proc_boot_cfg = ti_sci_cmd_set_proc_boot_cfg; + pops->set_proc_boot_ctrl = ti_sci_cmd_set_proc_boot_ctrl; + pops->proc_auth_boot_image = ti_sci_cmd_proc_auth_boot_image; + pops->get_proc_boot_status = ti_sci_cmd_get_proc_boot_status; } /** diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index 714a066985..a2ed9b6ea9 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -41,6 +41,15 @@ #define TI_SCI_MSG_QUERY_CLOCK_FREQ 0x010d #define TI_SCI_MSG_GET_CLOCK_FREQ 0x010e +/* Processor Control Messages */ +#define TISCI_MSG_PROC_REQUEST 0xc000 +#define TISCI_MSG_PROC_RELEASE 0xc001 +#define TISCI_MSG_PROC_HANDOVER 0xc005 +#define TISCI_MSG_SET_PROC_BOOT_CONFIG 0xc100 +#define TISCI_MSG_SET_PROC_BOOT_CTRL 0xc101 +#define TISCI_MSG_PROC_AUTH_BOOT_IMIAGE 0xc120 +#define TISCI_MSG_GET_PROC_BOOT_STATUS 0xc400 + /** * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses * @type: Type of messages: One of TI_SCI_MSG* values @@ -496,4 +505,176 @@ struct ti_sci_msg_resp_get_clock_freq { u64 freq_hz; } __packed; +#define TISCI_ADDR_LOW_MASK GENMASK_ULL(31, 0) +#define TISCI_ADDR_HIGH_MASK GENMASK_ULL(63, 32) +#define TISCI_ADDR_HIGH_SHIFT 32 + +/** + * struct ti_sci_msg_req_proc_request - Request a processor + * + * @hdr: Generic Header + * @processor_id: ID of processor + * + * Request type is TISCI_MSG_PROC_REQUEST, response is a generic ACK/NACK + * message. + */ +struct ti_sci_msg_req_proc_request { + struct ti_sci_msg_hdr hdr; + u8 processor_id; +} __packed; + +/** + * struct ti_sci_msg_req_proc_release - Release a processor + * + * @hdr: Generic Header + * @processor_id: ID of processor + * + * Request type is TISCI_MSG_PROC_RELEASE, response is a generic ACK/NACK + * message. + */ +struct ti_sci_msg_req_proc_release { + struct ti_sci_msg_hdr hdr; + u8 processor_id; +} __packed; + +/** + * struct ti_sci_msg_req_proc_handover - Handover a processor to a host + * + * @hdr: Generic Header + * @processor_id: ID of processor + * @host_id: New Host we want to give control to + * + * Request type is TISCI_MSG_PROC_HANDOVER, response is a generic ACK/NACK + * message. + */ +struct ti_sci_msg_req_proc_handover { + struct ti_sci_msg_hdr hdr; + u8 processor_id; + u8 host_id; +} __packed; + +/* A53 Config Flags */ +#define PROC_BOOT_CFG_FLAG_ARMV8_DBG_EN 0x00000001 +#define PROC_BOOT_CFG_FLAG_ARMV8_DBG_NIDEN 0x00000002 +#define PROC_BOOT_CFG_FLAG_ARMV8_DBG_SPIDEN 0x00000004 +#define PROC_BOOT_CFG_FLAG_ARMV8_DBG_SPNIDEN 0x00000008 +#define PROC_BOOT_CFG_FLAG_ARMV8_AARCH32 0x00000100 + +/* R5 Config Flags */ +#define PROC_BOOT_CFG_FLAG_R5_DBG_EN 0x00000001 +#define PROC_BOOT_CFG_FLAG_R5_DBG_NIDEN 0x00000002 +#define PROC_BOOT_CFG_FLAG_R5_LOCKSTEP 0x00000100 +#define PROC_BOOT_CFG_FLAG_R5_TEINIT 0x00000200 +#define PROC_BOOT_CFG_FLAG_R5_NMFI_EN 0x00000400 +#define PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE 0x00000800 +#define PROC_BOOT_CFG_FLAG_R5_BTCM_EN 0x00001000 +#define PROC_BOOT_CFG_FLAG_R5_ATCM_EN 0x00002000 + +/** + * struct ti_sci_msg_req_set_proc_boot_config - Set Processor boot configuration + * @hdr: Generic Header + * @processor_id: ID of processor + * @bootvector_low: Lower 32bit (Little Endian) of boot vector + * @bootvector_high: Higher 32bit (Little Endian) of boot vector + * @config_flags_set: Optional Processor specific Config Flags to set. + * Setting a bit here implies required bit sets to 1. + * @config_flags_clear: Optional Processor specific Config Flags to clear. + * Setting a bit here implies required bit gets cleared. + * + * Request type is TISCI_MSG_SET_PROC_BOOT_CONFIG, response is a generic + * ACK/NACK message. + */ +struct ti_sci_msg_req_set_proc_boot_config { + struct ti_sci_msg_hdr hdr; + u8 processor_id; + u32 bootvector_low; + u32 bootvector_high; + u32 config_flags_set; + u32 config_flags_clear; +} __packed; + +/* R5 Control Flags */ +#define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001 + +/** + * struct ti_sci_msg_req_set_proc_boot_ctrl - Set Processor boot control flags + * @hdr: Generic Header + * @processor_id: ID of processor + * @control_flags_set: Optional Processor specific Control Flags to set. + * Setting a bit here implies required bit sets to 1. + * @control_flags_clear:Optional Processor specific Control Flags to clear. + * Setting a bit here implies required bit gets cleared. + * + * Request type is TISCI_MSG_SET_PROC_BOOT_CTRL, response is a generic ACK/NACK + * message. + */ +struct ti_sci_msg_req_set_proc_boot_ctrl { + struct ti_sci_msg_hdr hdr; + u8 processor_id; + u32 control_flags_set; + u32 control_flags_clear; +} __packed; + +/** + * struct ti_sci_msg_req_proc_auth_start_image - Authenticate and start image + * @hdr: Generic Header + * @processor_id: ID of processor + * @cert_addr_low: Lower 32bit (Little Endian) of certificate + * @cert_addr_high: Higher 32bit (Little Endian) of certificate + * + * Request type is TISCI_MSG_PROC_AUTH_BOOT_IMAGE, response is a generic + * ACK/NACK message. + */ +struct ti_sci_msg_req_proc_auth_boot_image { + struct ti_sci_msg_hdr hdr; + u8 processor_id; + u32 cert_addr_low; + u32 cert_addr_high; +} __packed; + +/** + * struct ti_sci_msg_req_get_proc_boot_status - Get processor boot status + * @hdr: Generic Header + * @processor_id: ID of processor + * + * Request type is TISCI_MSG_GET_PROC_BOOT_STATUS, response is appropriate + * message, or NACK in case of inability to satisfy request. + */ +struct ti_sci_msg_req_get_proc_boot_status { + struct ti_sci_msg_hdr hdr; + u8 processor_id; +} __packed; + +/* ARMv8 Status Flags */ +#define PROC_BOOT_STATUS_FLAG_ARMV8_WFE 0x00000001 +#define PROC_BOOT_STATUS_FLAG_ARMV8_WFI 0x00000002 + +/* R5 Status Flags */ +#define PROC_BOOT_STATUS_FLAG_R5_WFE 0x00000001 +#define PROC_BOOT_STATUS_FLAG_R5_WFI 0x00000002 +#define PROC_BOOT_STATUS_FLAG_R5_CLK_GATED 0x00000004 +#define PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED 0x00000100 + +/** + * struct ti_sci_msg_resp_get_proc_boot_status - Processor boot status response + * @hdr: Generic Header + * @processor_id: ID of processor + * @bootvector_low: Lower 32bit (Little Endian) of boot vector + * @bootvector_high: Higher 32bit (Little Endian) of boot vector + * @config_flags: Optional Processor specific Config Flags set. + * @control_flags: Optional Processor specific Control Flags. + * @status_flags: Optional Processor specific Status Flags set. + * + * Response to TISCI_MSG_GET_PROC_BOOT_STATUS. + */ +struct ti_sci_msg_resp_get_proc_boot_status { + struct ti_sci_msg_hdr hdr; + u8 processor_id; + u32 bootvector_low; + u32 bootvector_high; + u32 config_flags; + u32 control_flags; + u32 status_flags; +} __packed; + #endif /* __TI_SCI_H */ diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index e3ce993fa3..30298ee28e 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -223,18 +223,55 @@ struct ti_sci_core_ops { int (*reboot_device)(const struct ti_sci_handle *handle); }; +/** + * struct ti_sci_proc_ops - Processor specific operations. + * + * @proc_request: Request for controlling a physical processor. + * The requesting host should be in the processor access list. + * @proc_release: Relinquish a physical processor control + * @proc_handover: Handover a physical processor control to another host + * in the permitted list. + * @set_proc_boot_cfg: Base configuration of the processor + * @set_proc_boot_ctrl: Setup limited control flags in specific cases. + * @proc_auth_boot_image: + * @get_proc_boot_status: Get the state of physical processor + * + * NOTE: for all these functions, the following parameters are generic in + * nature: + * -handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle + * -pid: Processor ID + * + */ +struct ti_sci_proc_ops { + int (*proc_request)(const struct ti_sci_handle *handle, u8 pid); + int (*proc_release)(const struct ti_sci_handle *handle, u8 pid); + int (*proc_handover)(const struct ti_sci_handle *handle, u8 pid, + u8 hid); + int (*set_proc_boot_cfg)(const struct ti_sci_handle *handle, u8 pid, + u64 bv, u32 cfg_set, u32 cfg_clr); + int (*set_proc_boot_ctrl)(const struct ti_sci_handle *handle, u8 pid, + u32 ctrl_set, u32 ctrl_clr); + int (*proc_auth_boot_image)(const struct ti_sci_handle *handle, u8 pid, + u64 caddr); + int (*get_proc_boot_status)(const struct ti_sci_handle *handle, u8 pid, + u64 *bv, u32 *cfg_flags, u32 *ctrl_flags, + u32 *sts_flags); +}; + /** * struct ti_sci_ops - Function support for TI SCI * @board_ops: Miscellaneous operations * @dev_ops: Device specific operations * @clk_ops: Clock specific operations * @core_ops: Core specific operations + * @proc_ops: Processor specific operations */ struct ti_sci_ops { struct ti_sci_board_ops board_ops; struct ti_sci_dev_ops dev_ops; struct ti_sci_clk_ops clk_ops; struct ti_sci_core_ops core_ops; + struct ti_sci_proc_ops proc_ops; }; /** From patchwork Tue Aug 21 14:31:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960464 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="BjaFhsLI"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vttw1XR8z9s3x for ; Wed, 22 Aug 2018 00:52:24 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id D4CB5C21E13; Tue, 21 Aug 2018 14:44:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 320B9C21EC5; Tue, 21 Aug 2018 14:37:06 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id E4713C21E35; Tue, 21 Aug 2018 14:33:44 +0000 (UTC) Received: from lelv0143.ext.ti.com (lelv0143.ext.ti.com [198.47.23.248]) by lists.denx.de (Postfix) with ESMTPS id D17AFC21E0B for ; Tue, 21 Aug 2018 14:33:40 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXd85127847; Tue, 21 Aug 2018 09:33:39 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1534862019; bh=Lo3+InoDAQVR5Qp4nZne//9X9/Tzcs56DDJXn8kU0TU=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=BjaFhsLIMhMcOT3yDkVAtCzoTioS0FkM86ezvTtVimftEd2dbFcHVrKnyXdFk7TdD Hlzjv8l5ZAlWfSgI1LIG8IF9V2S11Jo/V631bJIZA2B52r9QwlMWdQVCZt1rz7myyd IEXJa9uiSUNa6E9QuWYLpvf/uS/tCnnitbmNkaes= Received: from DFLE100.ent.ti.com (dfle100.ent.ti.com [10.64.6.21]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXdfl018733; Tue, 21 Aug 2018 09:33:39 -0500 Received: from DFLE112.ent.ti.com (10.64.6.33) by DFLE100.ent.ti.com (10.64.6.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:39 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE112.ent.ti.com (10.64.6.33) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:39 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhS016556; Tue, 21 Aug 2018 09:33:37 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:45 +0530 Message-ID: <20180821143203.29142-8-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 07/25] dm: firmware: Automatically bind child devices X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Andreas Dannenberg To support scenarios where a firmware device node has subnodes that have their own drivers automatically scan the DT and bind those when the firmware device gets bound. Signed-off-by: Andreas Dannenberg Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- drivers/firmware/firmware-uclass.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/firmware/firmware-uclass.c b/drivers/firmware/firmware-uclass.c index d09923595b..3d33b6deba 100644 --- a/drivers/firmware/firmware-uclass.c +++ b/drivers/firmware/firmware-uclass.c @@ -7,4 +7,7 @@ UCLASS_DRIVER(firmware) = { .id = UCLASS_FIRMWARE, .name = "firmware", +#if CONFIG_IS_ENABLED(OF_CONTROL) + .post_bind = dm_scan_fdt_dev, +#endif }; From patchwork Tue Aug 21 14:31:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960443 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="XuSsBq9I"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtjm2hzCz9s5b for ; Wed, 22 Aug 2018 00:44:28 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 018F9C21E36; Tue, 21 Aug 2018 14:38:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 045D2C21E29; Tue, 21 Aug 2018 14:34:42 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id ABA3BC21C6A; Tue, 21 Aug 2018 14:33:47 +0000 (UTC) Received: from lelv0143.ext.ti.com (lelv0143.ext.ti.com [198.47.23.248]) by lists.denx.de (Postfix) with ESMTPS id 26893C21E49 for ; Tue, 21 Aug 2018 14:33:43 +0000 (UTC) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXfMI127858; Tue, 21 Aug 2018 09:33:41 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1534862021; bh=sxIeHzThy/rosnAKD6BFOZlb8XUEfyDOW9vtlgC4jJs=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=XuSsBq9ILUD8l4pOvV1rdrvcXmtwoVPe0zWarvf9PhtuJCOhVsEZQJZyfU6hJIqh8 RRfciAe9ysAtKfKumNwnMmhoR1sn9cYAgA/wm0AXLzzod8baKLNcvsS517Iv3D0ms4 Rz4bLaMBmJvzv7nrq04BT8qp8AmjveXSncOovtLE= Received: from DFLE109.ent.ti.com (dfle109.ent.ti.com [10.64.6.30]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXfVY011105; Tue, 21 Aug 2018 09:33:41 -0500 Received: from DFLE115.ent.ti.com (10.64.6.36) by DFLE109.ent.ti.com (10.64.6.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:41 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE115.ent.ti.com (10.64.6.36) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:41 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhT016556; Tue, 21 Aug 2018 09:33:39 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:46 +0530 Message-ID: <20180821143203.29142-9-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 08/25] dm: reset: Update uclass to allow querying reset status X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Andreas Dannenberg Add a reset operations function pointer to support querying the current status of a reset control. Signed-off-by: Andreas Dannenberg Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- drivers/reset/reset-uclass.c | 9 +++++++++ include/reset-uclass.h | 8 ++++++++ include/reset.h | 14 ++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c index 3899537635..89e39c6b5a 100644 --- a/drivers/reset/reset-uclass.c +++ b/drivers/reset/reset-uclass.c @@ -192,6 +192,15 @@ int reset_deassert_bulk(struct reset_ctl_bulk *bulk) return 0; } +int reset_status(struct reset_ctl *reset_ctl) +{ + struct reset_ops *ops = reset_dev_ops(reset_ctl->dev); + + debug("%s(reset_ctl=%p)\n", __func__, reset_ctl); + + return ops->rst_status(reset_ctl); +} + int reset_release_all(struct reset_ctl *reset_ctl, int count) { int i, ret; diff --git a/include/reset-uclass.h b/include/reset-uclass.h index c17d738b31..7b5cc3cb3b 100644 --- a/include/reset-uclass.h +++ b/include/reset-uclass.h @@ -76,6 +76,14 @@ struct reset_ops { * @return 0 if OK, or a negative error code. */ int (*rst_deassert)(struct reset_ctl *reset_ctl); + /** + * rst_status - Check reset signal status. + * + * @reset_ctl: The reset signal to check. + * @return 0 if deasserted, positive if asserted, or a negative + * error code. + */ + int (*rst_status)(struct reset_ctl *reset_ctl); }; #endif diff --git a/include/reset.h b/include/reset.h index a7bbc1c331..34ebb096dd 100644 --- a/include/reset.h +++ b/include/reset.h @@ -206,6 +206,15 @@ int reset_deassert(struct reset_ctl *reset_ctl); */ int reset_deassert_bulk(struct reset_ctl_bulk *bulk); +/** + * rst_status - Check reset signal status. + * + * @reset_ctl: The reset signal to check. + * @return 0 if deasserted, positive if asserted, or a negative + * error code. + */ +int reset_status(struct reset_ctl *reset_ctl); + /** * reset_release_all - Assert/Free an array of previously requested resets. * @@ -279,6 +288,11 @@ static inline int reset_deassert_bulk(struct reset_ctl_bulk *bulk) return 0; } +static inline int reset_status(struct reset_ctl *reset_ctl) +{ + return -ENOTSUPP; +} + static inline int reset_release_all(struct reset_ctl *reset_ctl, int count) { return 0; From patchwork Tue Aug 21 14:31:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960457 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="CLTRKvLD"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtqR0nynz9s3x for ; Wed, 22 Aug 2018 00:49:23 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id CDC9EC21E2C; Tue, 21 Aug 2018 14:42:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 86BFEC21E6C; Tue, 21 Aug 2018 14:36:05 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id B0842C21DFD; Tue, 21 Aug 2018 14:33:50 +0000 (UTC) Received: from lelv0143.ext.ti.com (lelv0143.ext.ti.com [198.47.23.248]) by lists.denx.de (Postfix) with ESMTPS id 4F3A4C21E29 for ; Tue, 21 Aug 2018 14:33:45 +0000 (UTC) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXhBu127884; Tue, 21 Aug 2018 09:33:43 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1534862023; bh=e9OvCIqZ1QmmX10uwDIH1FUSj0/EvEBBdsBttK1JGkw=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=CLTRKvLDfa1s4ZEIdr3FwdzdRefFVJjO6ihiasqD+u44v/GXqa6twgOAqph0v+kxf xD0ybpXfGHifYzbzY+LEBQnHvL3dNKVu55nW8ihei5yEidyj11qv8KRMI0Ug21cE8S CyiSE5H08n+R4oMdfDywEwkcCYhdcCscxC7FaMds= Received: from DFLE103.ent.ti.com (dfle103.ent.ti.com [10.64.6.24]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXha0011142; Tue, 21 Aug 2018 09:33:43 -0500 Received: from DFLE102.ent.ti.com (10.64.6.23) by DFLE103.ent.ti.com (10.64.6.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:43 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE102.ent.ti.com (10.64.6.23) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:43 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhU016556; Tue, 21 Aug 2018 09:33:41 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:47 +0530 Message-ID: <20180821143203.29142-10-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 09/25] reset: Extend reset control with an optional data field X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Andreas Dannenberg Some systems require more than a single ID to identify and configure any reset provider. For those scenarios add an optional data field to the reset control structure. Signed-off-by: Andreas Dannenberg Signed-off-by: Lokesh Vutla Tested-by: Tom Rini --- include/reset.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/include/reset.h b/include/reset.h index 34ebb096dd..bc495a90c2 100644 --- a/include/reset.h +++ b/include/reset.h @@ -40,10 +40,12 @@ struct udevice; * * @dev: The device which implements the reset signal. * @id: The reset signal ID within the provider. + * @data: An optional data field for scenarios where a single integer ID is not + * sufficient. If used, it can be populated through an .of_xlate op and + * processed during the various reset ops. * - * Currently, the reset API assumes that a single integer ID is enough to - * identify and configure any reset signal for any reset provider. If this - * assumption becomes invalid in the future, the struct could be expanded to + * Should additional information to identify and configure any reset signal + * for any provider be required in the future, the struct could be expanded to * either (a) add more fields to allow reset providers to store additional * information, or (b) replace the id field with an opaque pointer, which the * provider would dynamically allocated during its .of_xlate op, and process @@ -53,10 +55,10 @@ struct udevice; struct reset_ctl { struct udevice *dev; /* - * Written by of_xlate. We assume a single id is enough for now. In the - * future, we might add more fields here. + * Written by of_xlate. In the future, we might add more fields here. */ unsigned long id; + unsigned long data; }; /** From patchwork Tue Aug 21 14:31:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960427 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtbd35jjz9s4v for ; Wed, 22 Aug 2018 00:39:09 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id C7AA7C21E3A; Tue, 21 Aug 2018 14:38:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 8D53FC21E2F; Tue, 21 Aug 2018 14:34:46 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 8C95DC21DFD; Tue, 21 Aug 2018 14:33:51 +0000 (UTC) Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) by lists.denx.de (Postfix) with ESMTPS id 954E4C21E57 for ; Tue, 21 Aug 2018 14:33:47 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXkTS044259; Tue, 21 Aug 2018 09:33:46 -0500 Received: from DLEE105.ent.ti.com (dlee105.ent.ti.com [157.170.170.35]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXkXK018819; Tue, 21 Aug 2018 09:33:46 -0500 Received: from DLEE101.ent.ti.com (157.170.170.31) by DLEE105.ent.ti.com (157.170.170.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:45 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE101.ent.ti.com (157.170.170.31) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:45 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhV016556; Tue, 21 Aug 2018 09:33:44 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:48 +0530 Message-ID: <20180821143203.29142-11-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 10/25] reset: Introduce TI System Control Interface (TI SCI) reset driver X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Andreas Dannenberg Some TI Keystone 2 and K3 family of SoCs contain a system controller (like the Power Management Micro Controller (PMMC) on 66AK2G SoCs and the Device Management and Security Controller on AM65x SoCs) that manage the low-level device control (like clocks, resets etc) for the various hardware modules present on the SoC. These device control operations are provided to the host processor OS through a communication protocol called the TI System Control Interface (TI SCI) protocol. This patch adds a reset driver that communicates to the system controller over the TI SCI protocol for performing reset management of various devices present on the SoC. Various reset functionalities are achieved by the means of different TI SCI device operations provided by the TI SCI framework. This code is loosely based on the drivers/reset/reset-ti-sci.c driver of the Linux kernel. Signed-off-by: Andreas Dannenberg Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- .../reset/ti,sci-reset.txt | 54 +++++ drivers/reset/Kconfig | 8 + drivers/reset/Makefile | 1 + drivers/reset/reset-ti-sci.c | 206 ++++++++++++++++++ 4 files changed, 269 insertions(+) create mode 100644 doc/device-tree-bindings/reset/ti,sci-reset.txt create mode 100644 drivers/reset/reset-ti-sci.c diff --git a/doc/device-tree-bindings/reset/ti,sci-reset.txt b/doc/device-tree-bindings/reset/ti,sci-reset.txt new file mode 100644 index 0000000000..e7e2d13f9f --- /dev/null +++ b/doc/device-tree-bindings/reset/ti,sci-reset.txt @@ -0,0 +1,54 @@ +Texas Instruments TI SCI Reset Controller +========================================= + +Some TI SoCs contain a system controller (like the SYSFW, etc...) that is +responsible for controlling the state of the IPs that are present. +Communication between the host processor running an OS and the system +controller happens through a protocol known as TI SCI [1]. + +[1] http://processors.wiki.ti.com/index.php/TISCI + +Reset Controller Node +===================== +The reset controller node represents the resets of various hardware modules +present on the SoC managed by the SYSFW. Because this relies on the TI SCI +protocol to communicate with the SYSFW it must be a child of the sysfw node. + +Required Properties: +-------------------- + - compatible: Must be "ti,sci-reset" + - #reset-cells: Must be 2. Please see the reset consumer node below for + usage details. + +Example (AM65x): +---------------- + sysfw: sysfw { + compatible = "ti,am654-system-controller"; + ... + k3_reset: reset-controller { + compatible = "ti,sci-reset"; + #reset-cells = <2>; + }; + }; + +Reset Consumers +=============== +Each of the reset consumer nodes should have the following properties, +in addition to their own properties. + +Required Properties: +-------------------- + - resets: A phandle and reset specifier pair, one pair for each reset signal + that affects the device, or that the device manages. The phandle + should point to the TI SCI reset controller node, and the reset + specifier should have 2 cell-values. The first cell should contain + the device ID. The second cell should contain the reset mask value + used by system controller. + +Example (AM65x): +---------------- + uart2: serial@02800000 { + compatible = "ti,omap4-uart"; + ... + resets = <&k3_reset 5 1>; + }; diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 33c39b7fb6..9c5208b7da 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -49,6 +49,14 @@ config TEGRA186_RESET Enable support for manipulating Tegra's on-SoC reset signals via IPC requests to the BPMP (Boot and Power Management Processor). +config RESET_TI_SCI + bool "TI System Control Interface (TI SCI) reset driver" + depends on DM_RESET && TI_SCI_PROTOCOL + help + This enables the reset driver support over TI System Control Interface + available on some new TI's SoCs. If you wish to use reset resources + managed by the TI System Controller, say Y here. Otherwise, say N. + config RESET_BCM6345 bool "Reset controller driver for BCM6345" depends on DM_RESET && ARCH_BMIPS diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index ad08be4c8c..abdfa0c663 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_STI_RESET) += sti-reset.o obj-$(CONFIG_STM32_RESET) += stm32-reset.o obj-$(CONFIG_TEGRA_CAR_RESET) += tegra-car-reset.o obj-$(CONFIG_TEGRA186_RESET) += tegra186-reset.o +obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o obj-$(CONFIG_AST2500_RESET) += ast2500-reset.o diff --git a/drivers/reset/reset-ti-sci.c b/drivers/reset/reset-ti-sci.c new file mode 100644 index 0000000000..c8a76dfb04 --- /dev/null +++ b/drivers/reset/reset-ti-sci.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Texas Instruments System Control Interface (TI SCI) reset driver + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Andreas Dannenberg + * + * Loosely based on Linux kernel reset-ti-sci.c... + */ + +#include +#include +#include +#include +#include + +/** + * struct ti_sci_reset_data - reset controller information structure + * @sci: TI SCI handle used for communication with system controller + */ +struct ti_sci_reset_data { + const struct ti_sci_handle *sci; +}; + +static int ti_sci_reset_probe(struct udevice *dev) +{ + struct ti_sci_reset_data *data = dev_get_priv(dev); + + debug("%s(dev=%p)\n", __func__, dev); + + if (!data) + return -ENOMEM; + + /* Store handle for communication with the system controller */ + data->sci = ti_sci_get_handle(dev); + if (IS_ERR(data->sci)) + return PTR_ERR(data->sci); + + return 0; +} + +static int ti_sci_reset_of_xlate(struct reset_ctl *rst, + struct ofnode_phandle_args *args) +{ + debug("%s(rst=%p, args_count=%d)\n", __func__, rst, args->args_count); + + if (args->args_count != 2) { + debug("Invalid args_count: %d\n", args->args_count); + return -EINVAL; + } + + /* + * On TI SCI-based devices, the reset provider id field is used as a + * device ID, and the data field is used as the associated reset mask. + */ + rst->id = args->args[0]; + rst->data = args->args[1]; + + return 0; +} + +static int ti_sci_reset_request(struct reset_ctl *rst) +{ + debug("%s(rst=%p)\n", __func__, rst); + return 0; +} + +static int ti_sci_reset_free(struct reset_ctl *rst) +{ + debug("%s(rst=%p)\n", __func__, rst); + return 0; +} + +/** + * ti_sci_reset_set() - program a device's reset + * @rst: Handle to a single reset signal + * @assert: boolean flag to indicate assert or deassert + * + * This is a common internal function used to assert or deassert a device's + * reset using the TI SCI protocol. The device's reset is asserted if the + * @assert argument is true, or deasserted if @assert argument is false. + * The mechanism itself is a read-modify-write procedure, the current device + * reset register is read using a TI SCI device operation, the new value is + * set or un-set using the reset's mask, and the new reset value written by + * using another TI SCI device operation. + * + * Return: 0 for successful request, else a corresponding error value + */ +static int ti_sci_reset_set(struct reset_ctl *rst, bool assert) +{ + struct ti_sci_reset_data *data = dev_get_priv(rst->dev); + const struct ti_sci_handle *sci = data->sci; + const struct ti_sci_dev_ops *dops = &sci->ops.dev_ops; + u32 reset_state; + int ret; + + ret = dops->get_device_resets(sci, rst->id, &reset_state); + if (ret) { + dev_err(rst->dev, "%s: get_device_resets failed (%d)\n", + __func__, ret); + return ret; + } + + if (assert) + reset_state |= rst->data; + else + reset_state &= ~rst->data; + + ret = dops->set_device_resets(sci, rst->id, reset_state); + if (ret) { + dev_err(rst->dev, "%s: set_device_resets failed (%d)\n", + __func__, ret); + return ret; + } + + return 0; +} + +/** + * ti_sci_reset_assert() - assert device reset + * @rst: Handle to a single reset signal + * + * This function implements the reset driver op to assert a device's reset + * using the TI SCI protocol. This invokes the function ti_sci_reset_set() + * with the corresponding parameters as passed in, but with the @assert + * argument set to true for asserting the reset. + * + * Return: 0 for successful request, else a corresponding error value + */ +static int ti_sci_reset_assert(struct reset_ctl *rst) +{ + debug("%s(rst=%p)\n", __func__, rst); + return ti_sci_reset_set(rst, true); +} + +/** + * ti_sci_reset_deassert() - deassert device reset + * @rst: Handle to a single reset signal + * + * This function implements the reset driver op to deassert a device's reset + * using the TI SCI protocol. This invokes the function ti_sci_reset_set() + * with the corresponding parameters as passed in, but with the @assert + * argument set to false for deasserting the reset. + * + * Return: 0 for successful request, else a corresponding error value + */ +static int ti_sci_reset_deassert(struct reset_ctl *rst) +{ + debug("%s(rst=%p)\n", __func__, rst); + return ti_sci_reset_set(rst, false); +} + +/** + * ti_sci_reset_status() - check device reset status + * @rst: Handle to a single reset signal + * + * This function implements the reset driver op to return the status of a + * device's reset using the TI SCI protocol. The reset register value is read + * by invoking the TI SCI device operation .get_device_resets(), and the + * status of the specific reset is extracted and returned using this reset's + * reset mask. + * + * Return: 0 if reset is deasserted, or a non-zero value if reset is asserted + */ +static int ti_sci_reset_status(struct reset_ctl *rst) +{ + struct ti_sci_reset_data *data = dev_get_priv(rst->dev); + const struct ti_sci_handle *sci = data->sci; + const struct ti_sci_dev_ops *dops = &sci->ops.dev_ops; + u32 reset_state; + int ret; + + debug("%s(rst=%p)\n", __func__, rst); + + ret = dops->get_device_resets(sci, rst->id, &reset_state); + if (ret) { + dev_err(rst->dev, "%s: get_device_resets failed (%d)\n", + __func__, ret); + return ret; + } + + return reset_state & rst->data; +} + +static const struct udevice_id ti_sci_reset_of_match[] = { + { .compatible = "ti,sci-reset", }, + { /* sentinel */ }, +}; + +static struct reset_ops ti_sci_reset_ops = { + .of_xlate = ti_sci_reset_of_xlate, + .request = ti_sci_reset_request, + .free = ti_sci_reset_free, + .rst_assert = ti_sci_reset_assert, + .rst_deassert = ti_sci_reset_deassert, + .rst_status = ti_sci_reset_status, +}; + +U_BOOT_DRIVER(ti_sci_reset) = { + .name = "ti-sci-reset", + .id = UCLASS_RESET, + .of_match = ti_sci_reset_of_match, + .probe = ti_sci_reset_probe, + .priv_auto_alloc_size = sizeof(struct ti_sci_reset_data), + .ops = &ti_sci_reset_ops, +}; From patchwork Tue Aug 21 14:31:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960472 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="shb5RXXZ"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtzb5jlTz9s3x for ; Wed, 22 Aug 2018 00:56:27 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 67323C21E07; Tue, 21 Aug 2018 14:40:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id C0C4FC21E18; Tue, 21 Aug 2018 14:35:26 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 45BC9C21E30; Tue, 21 Aug 2018 14:33:55 +0000 (UTC) Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) by lists.denx.de (Postfix) with ESMTPS id A4935C21DF3 for ; Tue, 21 Aug 2018 14:33:49 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXm6w115911; Tue, 21 Aug 2018 09:33:48 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1534862028; bh=RUB+GQl6InXomsTxarK/x2JY4lTYgYAwbTYKfe3lRGA=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=shb5RXXZfm/mZCd4rfrUmaa4nxGCY9f1d4dOK8zIaaGYvif8+AogLp5VVW834Ndep lDYUaxMH+1HGQgHOIGVTvY4ZScpZBGtsiDSmLNjwDg7HA+uEiY3BJryeFABsClvXXy dX6Lki0gmwZMU9E5ZorvmmdBBor1DvZP9S5Eaztg= Received: from DFLE115.ent.ti.com (dfle115.ent.ti.com [10.64.6.36]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXm20018860; Tue, 21 Aug 2018 09:33:48 -0500 Received: from DFLE101.ent.ti.com (10.64.6.22) by DFLE115.ent.ti.com (10.64.6.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:47 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE101.ent.ti.com (10.64.6.22) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:47 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhW016556; Tue, 21 Aug 2018 09:33:46 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:49 +0530 Message-ID: <20180821143203.29142-12-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 11/25] clk: Allow clock defaults to be set also during re-reloc state X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Andreas Dannenberg The earlier commit f4fcba5c5ba ("clk: implement clk_set_defaults()") which introduced the functionality for setting clock defaults such as rates and parents will skip the processing when executing in a re-reloc state. This for example can prevent the assigning of clock parents when running in SPL code. Go ahead and remove this limitation. Signed-off-by: Andreas Dannenberg Signed-off-by: Lokesh Vutla --- drivers/clk/clk-uclass.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index 2b15978e14..04b369aa5a 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -243,10 +243,6 @@ int clk_set_defaults(struct udevice *dev) { int ret; - /* If this is running pre-reloc state, don't take any action. */ - if (!(gd->flags & GD_FLG_RELOC)) - return 0; - debug("%s(%s)\n", __func__, dev_read_name(dev)); ret = clk_set_default_parents(dev); From patchwork Tue Aug 21 14:31:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960440 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtj069Phz9s5c for ; Wed, 22 Aug 2018 00:43:48 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 7553DC21E07; Tue, 21 Aug 2018 14:41:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id D6877C21E6A; Tue, 21 Aug 2018 14:35:30 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id B9FCDC21EB4; Tue, 21 Aug 2018 14:33:55 +0000 (UTC) Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) by lists.denx.de (Postfix) with ESMTPS id BB57CC21E3A for ; Tue, 21 Aug 2018 14:33:51 +0000 (UTC) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXo2b104735; Tue, 21 Aug 2018 09:33:50 -0500 Received: from DFLE107.ent.ti.com (dfle107.ent.ti.com [10.64.6.28]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXoR4011251; Tue, 21 Aug 2018 09:33:50 -0500 Received: from DFLE102.ent.ti.com (10.64.6.23) by DFLE107.ent.ti.com (10.64.6.28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:49 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE102.ent.ti.com (10.64.6.23) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:50 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhX016556; Tue, 21 Aug 2018 09:33:48 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:50 +0530 Message-ID: <20180821143203.29142-13-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 12/25] clk: Extend clock control with an optional data field X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Andreas Dannenberg Some systems require more than a single ID to identify and configure any clock provider. For those scenarios add an optional data field to the clock control structure. Signed-off-by: Andreas Dannenberg Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- include/clk.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/include/clk.h b/include/clk.h index f6d1cc53a1..c0a20cd47a 100644 --- a/include/clk.h +++ b/include/clk.h @@ -40,10 +40,12 @@ struct udevice; * * @dev: The device which implements the clock signal. * @id: The clock signal ID within the provider. + * @data: An optional data field for scenarios where a single integer ID is not + * sufficient. If used, it can be populated through an .of_xlate op and + * processed during the various clock ops. * - * Currently, the clock API assumes that a single integer ID is enough to - * identify and configure any clock signal for any clock provider. If this - * assumption becomes invalid in the future, the struct could be expanded to + * Should additional information to identify and configure any clock signal + * for any provider be required in the future, the struct could be expanded to * either (a) add more fields to allow clock providers to store additional * information, or (b) replace the id field with an opaque pointer, which the * provider would dynamically allocated during its .of_xlate op, and process @@ -53,10 +55,10 @@ struct udevice; struct clk { struct udevice *dev; /* - * Written by of_xlate. We assume a single id is enough for now. In the - * future, we might add more fields here. + * Written by of_xlate. In the future, we might add more fields here. */ unsigned long id; + unsigned long data; }; /** From patchwork Tue Aug 21 14:31:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960451 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtnV62jBz9s5c for ; Wed, 22 Aug 2018 00:47:42 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 7A438C21C4A; Tue, 21 Aug 2018 14:41:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 58323C21EB9; Tue, 21 Aug 2018 14:35:37 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 1B6DCC21E75; Tue, 21 Aug 2018 14:34:00 +0000 (UTC) Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) by lists.denx.de (Postfix) with ESMTPS id 8207DC21E35 for ; Tue, 21 Aug 2018 14:33:54 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXqao044293; Tue, 21 Aug 2018 09:33:52 -0500 Received: from DLEE100.ent.ti.com (dlee100.ent.ti.com [157.170.170.30]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXq1Q018945; Tue, 21 Aug 2018 09:33:52 -0500 Received: from DLEE112.ent.ti.com (157.170.170.23) by DLEE100.ent.ti.com (157.170.170.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:52 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE112.ent.ti.com (157.170.170.23) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:52 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhY016556; Tue, 21 Aug 2018 09:33:50 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:51 +0530 Message-ID: <20180821143203.29142-14-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 13/25] clk: Introduce TI System Control Interface (TI SCI) clock driver X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Andreas Dannenberg Some TI Keystone 2 and K3 family of SoCs contain a system controller (like the Power Management Micro Controller (PMMC) on 66AK2G SoCs and the Device Management and Security Controller on AM65x SoCs) that manage the low-level device control (like clocks, resets etc) for the various hardware modules present on the SoC. These device control operations are provided to the host processor OS through a communication protocol called the TI System Control Interface (TI SCI) protocol. This patch adds a clock driver that communicates to the system controller over the TI SCI protocol for performing clock management of various devices present on the SoC. Various clock functionality is achieved by the means of different TI SCI device operations provided by the TI SCI framework. This code is loosely based on the drivers/clk/keystone/sci-clk.c driver of the Linux kernel. Signed-off-by: Andreas Dannenberg Signed-off-by: Vignesh R Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- doc/device-tree-bindings/clock/ti,sci-clk.txt | 53 +++++ drivers/clk/Kconfig | 8 + drivers/clk/Makefile | 1 + drivers/clk/clk-ti-sci.c | 217 ++++++++++++++++++ 4 files changed, 279 insertions(+) create mode 100644 doc/device-tree-bindings/clock/ti,sci-clk.txt create mode 100644 drivers/clk/clk-ti-sci.c diff --git a/doc/device-tree-bindings/clock/ti,sci-clk.txt b/doc/device-tree-bindings/clock/ti,sci-clk.txt new file mode 100644 index 0000000000..c6fe48200c --- /dev/null +++ b/doc/device-tree-bindings/clock/ti,sci-clk.txt @@ -0,0 +1,53 @@ +Texas Instruments TI SCI Clock Controller +========================================= + +All clocks on Texas Instruments' SoCs that contain a System Controller, +are only controlled by this entity. Communication between a host processor +running an OS and the System Controller happens through a protocol known +as TI SCI[1]. This clock implementation plugs into the common clock +framework and makes use of the TI SCI protocol on clock API requests. + +[1] http://processors.wiki.ti.com/index.php/TISCI + +Clock Controller Node +===================== +The clock controller node represents the clocks managed by the SYSFW. Because +this relies on the TI SCI protocol to communicate with the SYSFW it must be a +child of the sysfw node. + +Required Properties: +-------------------- +- compatible: Must be "ti,k2g-sci-clk" +- #clock-cells: Must be be 2. In clock consumers, this cell represents the + device ID and clock ID exposed by the SYSFW firmware. + +Example (AM65x): +---------------- + dmsc: dmsc { + compatible = "ti,k2g-sci"; + ... + k3_clks: clocks { + compatible = "ti,k2g-sci-clk"; + #clock-cells = <2>; + }; + }; + +Clock Consumers +=============== +Hardware blocks supplied by a clock should contain a "clocks" property that is +a phandle pointing to the clock controller node along with an index representing +the device id together with a clock ID to be passed to the SYSFW for device +control. + +Required Properties: +-------------------- +- clocks: phandle pointing to the corresponding clock node, an ID representing + the device, and an index representing a clock. + +Example (AM65x): +---------------- + uart2: serial@02800000 { + compatible = "ti,omap4-uart"; + ... + clocks = <&k3_clks 0x0007 1>; + }; diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 18bf8a6d28..45638caf96 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -54,6 +54,14 @@ config CLK_STM32F This clock driver adds support for RCC clock management for STM32F4 and STM32F7 SoCs. +config CLK_TI_SCI + bool "TI System Control Interface (TI SCI) clock driver" + depends on CLK && TI_SCI_PROTOCOL && OF_CONTROL + help + This enables the clock driver support over TI System Control Interface + available on some new TI's SoCs. If you wish to use clock resources + managed by the TI System Controller, say Y here. Otherwise, say N. + config CLK_HSDK bool "Enable cgu clock driver for HSDK" depends on CLK diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 146283c723..1544a1d82d 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -29,3 +29,4 @@ obj-$(CONFIG_MACH_PIC32) += clk_pic32.o obj-$(CONFIG_SANDBOX) += clk_sandbox.o obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o obj-$(CONFIG_STM32H7) += clk_stm32h7.o +obj-$(CONFIG_CLK_TI_SCI) += clk-ti-sci.o diff --git a/drivers/clk/clk-ti-sci.c b/drivers/clk/clk-ti-sci.c new file mode 100644 index 0000000000..c25415d410 --- /dev/null +++ b/drivers/clk/clk-ti-sci.c @@ -0,0 +1,217 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Texas Instruments System Control Interface (TI SCI) clock driver + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Andreas Dannenberg + * + * Loosely based on Linux kernel sci-clk.c... + */ + +#include +#include +#include +#include +#include + +/** + * struct ti_sci_clk_data - clock controller information structure + * @sci: TI SCI handle used for communication with system controller + */ +struct ti_sci_clk_data { + const struct ti_sci_handle *sci; +}; + +static int ti_sci_clk_probe(struct udevice *dev) +{ + struct ti_sci_clk_data *data = dev_get_priv(dev); + + debug("%s(dev=%p)\n", __func__, dev); + + if (!data) + return -ENOMEM; + + /* Store handle for communication with the system controller */ + data->sci = ti_sci_get_handle(dev); + if (IS_ERR(data->sci)) + return PTR_ERR(data->sci); + + return 0; +} + +static int ti_sci_clk_of_xlate(struct clk *clk, + struct ofnode_phandle_args *args) +{ + debug("%s(clk=%p, args_count=%d)\n", __func__, clk, args->args_count); + + if (args->args_count != 2) { + debug("Invalid args_count: %d\n", args->args_count); + return -EINVAL; + } + + /* + * On TI SCI-based devices, the clock provider id field is used as a + * device ID, and the data field is used as the associated sub-ID. + */ + clk->id = args->args[0]; + clk->data = args->args[1]; + + return 0; +} + +static int ti_sci_clk_request(struct clk *clk) +{ + debug("%s(clk=%p)\n", __func__, clk); + return 0; +} + +static int ti_sci_clk_free(struct clk *clk) +{ + debug("%s(clk=%p)\n", __func__, clk); + return 0; +} + +static ulong ti_sci_clk_get_rate(struct clk *clk) +{ + struct ti_sci_clk_data *data = dev_get_priv(clk->dev); + const struct ti_sci_handle *sci = data->sci; + const struct ti_sci_clk_ops *cops = &sci->ops.clk_ops; + u64 current_freq; + int ret; + + debug("%s(clk=%p)\n", __func__, clk); + + ret = cops->get_freq(sci, clk->id, clk->data, ¤t_freq); + if (ret) { + dev_err(clk->dev, "%s: get_freq failed (%d)\n", __func__, ret); + return ret; + } + + debug("%s(current_freq=%llu)\n", __func__, current_freq); + + return current_freq; +} + +static ulong ti_sci_clk_set_rate(struct clk *clk, ulong rate) +{ + struct ti_sci_clk_data *data = dev_get_priv(clk->dev); + const struct ti_sci_handle *sci = data->sci; + const struct ti_sci_clk_ops *cops = &sci->ops.clk_ops; + int ret; + + debug("%s(clk=%p, rate=%lu)\n", __func__, clk, rate); + + /* Ask for exact frequency by using same value for min/target/max */ + ret = cops->set_freq(sci, clk->id, clk->data, rate, rate, rate); + if (ret) + dev_err(clk->dev, "%s: set_freq failed (%d)\n", __func__, ret); + + return ret; +} + +static int ti_sci_clk_set_parent(struct clk *clk, struct clk *parent) +{ + struct ti_sci_clk_data *data = dev_get_priv(clk->dev); + const struct ti_sci_handle *sci = data->sci; + const struct ti_sci_clk_ops *cops = &sci->ops.clk_ops; + u8 num_parents; + u8 parent_cid; + int ret; + + debug("%s(clk=%p, parent=%p)\n", __func__, clk, parent); + + /* Make sure the clock parent is valid for a given device ID */ + if (clk->id != parent->id) + return -EINVAL; + + /* Make sure clock has parents that can be set */ + ret = cops->get_num_parents(sci, clk->id, clk->data, &num_parents); + if (ret) { + dev_err(clk->dev, "%s: get_num_parents failed (%d)\n", + __func__, ret); + return ret; + } + if (num_parents < 2) { + dev_err(clk->dev, "%s: clock has no settable parents!\n", + __func__); + return -EINVAL; + } + + /* Make sure parent clock ID is valid */ + parent_cid = parent->data - clk->data - 1; + if (parent_cid >= num_parents) { + dev_err(clk->dev, "%s: invalid parent clock!\n", __func__); + return -EINVAL; + } + + /* Ready to proceed to configure the new clock parent */ + ret = cops->set_parent(sci, clk->id, clk->data, parent->data); + if (ret) + dev_err(clk->dev, "%s: set_parent failed (%d)\n", __func__, + ret); + + return ret; +} + +static int ti_sci_clk_enable(struct clk *clk) +{ + struct ti_sci_clk_data *data = dev_get_priv(clk->dev); + const struct ti_sci_handle *sci = data->sci; + const struct ti_sci_clk_ops *cops = &sci->ops.clk_ops; + int ret; + + debug("%s(clk=%p)\n", __func__, clk); + + /* + * Allow the System Controller to automatically manage the state of + * this clock. If the device is enabled, then the clock is enabled. + */ + ret = cops->put_clock(sci, clk->id, clk->data); + if (ret) + dev_err(clk->dev, "%s: put_clock failed (%d)\n", __func__, ret); + + return ret; +} + +static int ti_sci_clk_disable(struct clk *clk) +{ + struct ti_sci_clk_data *data = dev_get_priv(clk->dev); + const struct ti_sci_handle *sci = data->sci; + const struct ti_sci_clk_ops *cops = &sci->ops.clk_ops; + int ret; + + debug("%s(clk=%p)\n", __func__, clk); + + /* Unconditionally disable clock, regardless of state of the device */ + ret = cops->idle_clock(sci, clk->id, clk->data); + if (ret) + dev_err(clk->dev, "%s: idle_clock failed (%d)\n", __func__, + ret); + + return ret; +} + +static const struct udevice_id ti_sci_clk_of_match[] = { + { .compatible = "ti,k2g-sci-clk" }, + { /* sentinel */ }, +}; + +static struct clk_ops ti_sci_clk_ops = { + .of_xlate = ti_sci_clk_of_xlate, + .request = ti_sci_clk_request, + .free = ti_sci_clk_free, + .get_rate = ti_sci_clk_get_rate, + .set_rate = ti_sci_clk_set_rate, + .set_parent = ti_sci_clk_set_parent, + .enable = ti_sci_clk_enable, + .disable = ti_sci_clk_disable, +}; + +U_BOOT_DRIVER(ti_sci_clk) = { + .name = "ti-sci-clk", + .id = UCLASS_CLK, + .of_match = ti_sci_clk_of_match, + .probe = ti_sci_clk_probe, + .priv_auto_alloc_size = sizeof(struct ti_sci_clk_data), + .ops = &ti_sci_clk_ops, +}; From patchwork Tue Aug 21 14:31:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960444 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="vD7Guyoh"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtl32TCbz9s7X for ; Wed, 22 Aug 2018 00:45:34 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id B2EC0C21E02; Tue, 21 Aug 2018 14:41:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 277C3C21EA8; Tue, 21 Aug 2018 14:35:35 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id D911BC21E31; Tue, 21 Aug 2018 14:34:02 +0000 (UTC) Received: from lelv0143.ext.ti.com (lelv0143.ext.ti.com [198.47.23.248]) by lists.denx.de (Postfix) with ESMTPS id 98CE5C21E39 for ; Tue, 21 Aug 2018 14:33:56 +0000 (UTC) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXtwC128071; Tue, 21 Aug 2018 09:33:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1534862035; bh=KXDmKg4U2DbpNV8E+AycTLgkTKyIZCJf/gIsz3WXSjc=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=vD7GuyohuGbpthSn5wBTBZJxgMoMCi8hLnDo2962bjEnB9RgWDEL36UPsgrXr1XdO MDAMAsjjp1xFdTNTMYCLgMiHBzVO2lhQm/kIus5ErnCdpRWJ20BdAqRLi6gx0u0bLt GsklPHRuUVFfAyAH/Er1eW1HvjRbZ1QFUfZdM7ao= Received: from DLEE107.ent.ti.com (dlee107.ent.ti.com [157.170.170.37]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXt16011391; Tue, 21 Aug 2018 09:33:55 -0500 Received: from DLEE105.ent.ti.com (157.170.170.35) by DLEE107.ent.ti.com (157.170.170.37) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:54 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE105.ent.ti.com (157.170.170.35) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:54 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhZ016556; Tue, 21 Aug 2018 09:33:52 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:52 +0530 Message-ID: <20180821143203.29142-15-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 14/25] power domain: Add support for multiple powerdomains per device X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" There are cases where there are more than one power domain attached to the device inorder to get the device functional. So add support for enabling power domain based on the index. Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- drivers/power/domain/power-domain-uclass.c | 11 +++++++++-- include/power-domain.h | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/power/domain/power-domain-uclass.c b/drivers/power/domain/power-domain-uclass.c index 9e9ec4f419..2ea0ff24c7 100644 --- a/drivers/power/domain/power-domain-uclass.c +++ b/drivers/power/domain/power-domain-uclass.c @@ -28,7 +28,8 @@ static int power_domain_of_xlate_default(struct power_domain *power_domain, return 0; } -int power_domain_get(struct udevice *dev, struct power_domain *power_domain) +int power_domain_get_by_index(struct udevice *dev, + struct power_domain *power_domain, int index) { struct ofnode_phandle_args args; int ret; @@ -38,7 +39,8 @@ int power_domain_get(struct udevice *dev, struct power_domain *power_domain) debug("%s(dev=%p, power_domain=%p)\n", __func__, dev, power_domain); ret = dev_read_phandle_with_args(dev, "power-domains", - "#power-domain-cells", 0, 0, &args); + "#power-domain-cells", 0, index, + &args); if (ret) { debug("%s: dev_read_phandle_with_args failed: %d\n", __func__, ret); @@ -73,6 +75,11 @@ int power_domain_get(struct udevice *dev, struct power_domain *power_domain) return 0; } +int power_domain_get(struct udevice *dev, struct power_domain *power_domain) +{ + return power_domain_get_by_index(dev, power_domain, 0); +} + int power_domain_free(struct power_domain *power_domain) { struct power_domain_ops *ops = power_domain_dev_ops(power_domain->dev); diff --git a/include/power-domain.h b/include/power-domain.h index a558fbbdb2..0c6d77e813 100644 --- a/include/power-domain.h +++ b/include/power-domain.h @@ -97,6 +97,25 @@ int power_domain_get(struct udevice *dev, struct power_domain *power_domain) } #endif +/** + * power_domain_get_by_index - Get the indexed power domain for a device. + * + * @dev: The client device. + * @power_domain: A pointer to a power domain struct to initialize. + * @index: Power domain index to be powered on. + * + * @return 0 if OK, or a negative error code. + */ +#if CONFIG_IS_ENABLED(POWER_DOMAIN) +int power_domain_get_by_index(struct udevice *dev, + struct power_domain *power_domain, int index); +#else +int power_domain_get_by_index(struct udevice *dev, + struct power_domain *power_domain, int index) + return -ENOSYS; +} +#endif + /** * power_domain_free - Free a previously requested power domain. * From patchwork Tue Aug 21 14:31:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960458 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="YMG0URDe"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtrR73P8z9s5b for ; Wed, 22 Aug 2018 00:50:15 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 909B8C21E0B; Tue, 21 Aug 2018 14:43:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 2F654C21EBE; Tue, 21 Aug 2018 14:36:38 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id B4886C21EBE; Tue, 21 Aug 2018 14:34:04 +0000 (UTC) Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) by lists.denx.de (Postfix) with ESMTPS id C39EFC21E3A for ; Tue, 21 Aug 2018 14:33:58 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXvhR115996; Tue, 21 Aug 2018 09:33:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1534862037; bh=ARRQwo9FDvNH7VChgkzBH8GtAqg+THraKApjG2c5J4c=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=YMG0URDe0iGYMg6C8epycQYiLmsQUbNlEb+7WbpieEVU184C+vwWKN/0cK1cCmIk2 Y2+4WqLHZNAvNtQk4aKhh+QEnGGkhQAjWwKgPwCkp4mEWkGFo+xcVqzzZlaJUwcGnt J9RtB55r8qgKNpl0MdHA9sO25HG7als0aCoUYvVg= Received: from DLEE106.ent.ti.com (dlee106.ent.ti.com [157.170.170.36]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXvjt019021; Tue, 21 Aug 2018 09:33:57 -0500 Received: from DLEE101.ent.ti.com (157.170.170.31) by DLEE106.ent.ti.com (157.170.170.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:56 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE101.ent.ti.com (157.170.170.31) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:57 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKha016556; Tue, 21 Aug 2018 09:33:55 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:53 +0530 Message-ID: <20180821143203.29142-16-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 15/25] power domain: Introduce TI System Control Interface (TI SCI) power domain driver X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Andreas Dannenberg Some TI Keystone 2 and K3 family of SoCs contain a system controller (like the Power Management Micro Controller (PMMC) on 66AK2G SoCs and the Device Management and Security Controller on AM65x SoCs) that manage the low-level device control (like clocks, resets etc) for the various hardware modules present on the SoC. These device control operations are provided to the host processor OS through a communication protocol called the TI System Control Interface (TI SCI) protocol. This patch adds a power domain driver that communicates to the system controller over the TI SCI protocol for performing power management of various devices present on the SoC. Various power domain functionalities are achieved by the means of different TI SCI device operations provided by the TI SCI framework. This code is loosely based on the drivers/soc/ti/ti_sci_pm_domains.c driver of the Linux kernel. Signed-off-by: Andreas Dannenberg Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- .../power/ti,sci-pm-domain.txt | 52 +++++++++ drivers/power/domain/Kconfig | 7 ++ drivers/power/domain/Makefile | 1 + drivers/power/domain/ti-sci-power-domain.c | 107 ++++++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 doc/device-tree-bindings/power/ti,sci-pm-domain.txt create mode 100644 drivers/power/domain/ti-sci-power-domain.c diff --git a/doc/device-tree-bindings/power/ti,sci-pm-domain.txt b/doc/device-tree-bindings/power/ti,sci-pm-domain.txt new file mode 100644 index 0000000000..0e190e20fe --- /dev/null +++ b/doc/device-tree-bindings/power/ti,sci-pm-domain.txt @@ -0,0 +1,52 @@ +Texas Instruments TI SCI Generic Power Domain +============================================= + +Some TI SoCs contain a system controller (like the SYSFW, etc...) that is +responsible for controlling the state of the IPs that are present. +Communication between the host processor running an OS and the system +controller happens through a protocol known as TI SCI [1]. + +[1] http://processors.wiki.ti.com/index.php/TISCI + +PM Domain Node +============== +The PM domain node represents the global PM domain managed by the SYSFW. Because +this relies on the TI SCI protocol to communicate with the SYSFW it must be a +child of the sysfw node. + +Required Properties: +-------------------- +- compatible: Must be "ti,sci-pm-domain" +- #power-domain-cells: Must be 1 so that an id can be provided in each + device node. + +Example (AM65x): +---------------- + sysfw: sysfw { + compatible = "ti,am654-system-controller"; + ... + k3_pds: power-controller { + compatible = "ti,sci-pm-domain"; + #power-domain-cells = <1>; + }; + }; + +PM Domain Consumers +=================== +Hardware blocks belonging to a PM domain should contain a "power-domains" +property that is a phandle pointing to the corresponding PM domain node +along with an index representing the device id to be passed to the PMMC +for device control. + +Required Properties: +-------------------- +- power-domains: phandle pointing to the corresponding PM domain node + and an ID representing the device. + +Example (AM65x): +---------------- + uart2: serial@02800000 { + compatible = "ti,omap4-uart"; + ... + power-domains = <&k3_pds 0x3f>; + }; diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig index 7cfa761498..80b0b48b0f 100644 --- a/drivers/power/domain/Kconfig +++ b/drivers/power/domain/Kconfig @@ -31,4 +31,11 @@ config TEGRA186_POWER_DOMAIN Enable support for manipulating Tegra's on-SoC power domains via IPC requests to the BPMP (Boot and Power Management Processor). +config TI_SCI_POWER_DOMAIN + bool "Enable the TI SCI-based power domain driver" + depends on POWER_DOMAIN && TI_SCI_PROTOCOL + help + Generic power domain implementation for TI devices implementing the + TI SCI protocol. + endmenu diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile index 020eee2378..9c6399b722 100644 --- a/drivers/power/domain/Makefile +++ b/drivers/power/domain/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_BCM6328_POWER_DOMAIN) += bcm6328-power-domain.o obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain.o obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o obj-$(CONFIG_TEGRA186_POWER_DOMAIN) += tegra186-power-domain.o +obj-$(CONFIG_TI_SCI_POWER_DOMAIN) += ti-sci-power-domain.o diff --git a/drivers/power/domain/ti-sci-power-domain.c b/drivers/power/domain/ti-sci-power-domain.c new file mode 100644 index 0000000000..aafde62cbf --- /dev/null +++ b/drivers/power/domain/ti-sci-power-domain.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Texas Instruments System Control Interface (TI SCI) power domain driver + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Andreas Dannenberg + * + * Loosely based on Linux kernel ti_sci_pm_domains.c... + */ + +#include +#include +#include +#include +#include + +/** + * struct ti_sci_power_domain_data - pm domain controller information structure + * @sci: TI SCI handle used for communication with system controller + */ +struct ti_sci_power_domain_data { + const struct ti_sci_handle *sci; +}; + +static int ti_sci_power_domain_probe(struct udevice *dev) +{ + struct ti_sci_power_domain_data *data = dev_get_priv(dev); + + debug("%s(dev=%p)\n", __func__, dev); + + if (!data) + return -ENOMEM; + + /* Store handle for communication with the system controller */ + data->sci = ti_sci_get_handle(dev); + if (IS_ERR(data->sci)) + return PTR_ERR(data->sci); + + return 0; +} + +static int ti_sci_power_domain_request(struct power_domain *pd) +{ + debug("%s(pd=%p)\n", __func__, pd); + return 0; +} + +static int ti_sci_power_domain_free(struct power_domain *pd) +{ + debug("%s(pd=%p)\n", __func__, pd); + return 0; +} + +static int ti_sci_power_domain_on(struct power_domain *pd) +{ + struct ti_sci_power_domain_data *data = dev_get_priv(pd->dev); + const struct ti_sci_handle *sci = data->sci; + const struct ti_sci_dev_ops *dops = &sci->ops.dev_ops; + int ret; + + debug("%s(pd=%p)\n", __func__, pd); + + ret = dops->get_device(sci, pd->id); + if (ret) + dev_err(power_domain->dev, "%s: get_device failed (%d)\n", + __func__, ret); + + return ret; +} + +static int ti_sci_power_domain_off(struct power_domain *pd) +{ + struct ti_sci_power_domain_data *data = dev_get_priv(pd->dev); + const struct ti_sci_handle *sci = data->sci; + const struct ti_sci_dev_ops *dops = &sci->ops.dev_ops; + int ret; + + debug("%s(pd=%p)\n", __func__, pd); + + ret = dops->put_device(sci, pd->id); + if (ret) + dev_err(power_domain->dev, "%s: put_device failed (%d)\n", + __func__, ret); + + return ret; +} + +static const struct udevice_id ti_sci_power_domain_of_match[] = { + { .compatible = "ti,sci-pm-domain" }, + { /* sentinel */ } +}; + +static struct power_domain_ops ti_sci_power_domain_ops = { + .request = ti_sci_power_domain_request, + .free = ti_sci_power_domain_free, + .on = ti_sci_power_domain_on, + .off = ti_sci_power_domain_off, +}; + +U_BOOT_DRIVER(ti_sci_pm_domains) = { + .name = "ti-sci-pm-domains", + .id = UCLASS_POWER_DOMAIN, + .of_match = ti_sci_power_domain_of_match, + .probe = ti_sci_power_domain_probe, + .priv_auto_alloc_size = sizeof(struct ti_sci_power_domain_data), + .ops = &ti_sci_power_domain_ops, +}; From patchwork Tue Aug 21 14:31:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960480 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vv2b4lVDz9s3Z for ; Wed, 22 Aug 2018 00:59:03 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 5890CC21E62; Tue, 21 Aug 2018 14:45:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 509C5C21EA1; Tue, 21 Aug 2018 14:37:45 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 5B87EC21E49; Tue, 21 Aug 2018 14:34:05 +0000 (UTC) Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) by lists.denx.de (Postfix) with ESMTPS id CB89DC21E49 for ; Tue, 21 Aug 2018 14:34:00 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEXx1x104773; Tue, 21 Aug 2018 09:33:59 -0500 Received: from DFLE102.ent.ti.com (dfle102.ent.ti.com [10.64.6.23]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXx9s019062; Tue, 21 Aug 2018 09:33:59 -0500 Received: from DFLE114.ent.ti.com (10.64.6.35) by DFLE102.ent.ti.com (10.64.6.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:33:59 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE114.ent.ti.com (10.64.6.35) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:33:59 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhb016556; Tue, 21 Aug 2018 09:33:57 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:54 +0530 Message-ID: <20180821143203.29142-17-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 16/25] sysreset: Add TI System Control Interface (TI SCI) sysreset driver X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Andreas Dannenberg Devices from the TI K3 family of SoCs like the AM654x contain a Device Management and Security Controller (SYSFW) that manages the low-level device control (like clocks, resets etc) for the various hardware modules present on the SoC. These device control operations are provided to the host processor OS through a communication protocol called the TI System Control Interface (TI SCI) protocol. This patch adds a system reset driver that communicates to the system controller over the TI SCI protocol for allowing to perform a system- wide SoC reset. Signed-off-by: Andreas Dannenberg Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- .../sysreset/ti,sci-sysreset.txt | 29 ++++++++ drivers/sysreset/Kconfig | 7 ++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset-ti-sci.c | 73 +++++++++++++++++++ 4 files changed, 110 insertions(+) create mode 100644 doc/device-tree-bindings/sysreset/ti,sci-sysreset.txt create mode 100644 drivers/sysreset/sysreset-ti-sci.c diff --git a/doc/device-tree-bindings/sysreset/ti,sci-sysreset.txt b/doc/device-tree-bindings/sysreset/ti,sci-sysreset.txt new file mode 100644 index 0000000000..02704c6487 --- /dev/null +++ b/doc/device-tree-bindings/sysreset/ti,sci-sysreset.txt @@ -0,0 +1,29 @@ +Texas Instruments TI SCI System Reset Controller +================================================ + +Some TI SoCs contain a system controller (like the SYSFW, etc...) that is +responsible for controlling the state of the IPs that are present. +Communication between the host processor running an OS and the system +controller happens through a protocol known as TI SCI [1]. + +[1] http://processors.wiki.ti.com/index.php/TISCI + +System Reset Controller Node +============================ +The sysreset controller node represents the reset for the overall SoC +which is managed by the SYSFW. Because this relies on the TI SCI protocol +to communicate with the SYSFW it must be a child of the sysfw node. + +Required Properties: +-------------------- + - compatible: Must be "ti,sci-sysreset" + +Example (AM65x): +---------------- + sysfw: sysfw { + compatible = "ti,am654-system-controller"; + ... + k3_sysreset: sysreset-controller { + compatible = "ti,sci-sysreset"; + }; + }; diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index 9b2fda4d25..ed1d437fb0 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -36,6 +36,13 @@ config SYSRESET_PSCI Enable PSCI SYSTEM_RESET function call. To use this, PSCI firmware must be running on your system. +config SYSRESET_TI_SCI + bool "TI System Control Interface (TI SCI) system reset driver" + depends on TI_SCI_PROTOCOL + help + This enables the system reset driver support over TI System Control + Interface available on some new TI's SoCs. + endif config SYSRESET_SYSCON diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index 707f1d7469..02ee1df6b0 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_SYSRESET) += sysreset-uclass.o obj-$(CONFIG_SYSRESET_GPIO) += sysreset_gpio.o obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o +obj-$(CONFIG_SYSRESET_TI_SCI) += sysreset-ti-sci.o obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o obj-$(CONFIG_SYSRESET_X86) += sysreset_x86.o diff --git a/drivers/sysreset/sysreset-ti-sci.c b/drivers/sysreset/sysreset-ti-sci.c new file mode 100644 index 0000000000..890a607c4b --- /dev/null +++ b/drivers/sysreset/sysreset-ti-sci.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Texas Instruments System Control Interface (TI SCI) system reset driver + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Andreas Dannenberg + */ + +#include +#include +#include +#include +#include + +/** + * struct ti_sci_sysreset_data - sysreset controller information structure + * @sci: TI SCI handle used for communication with system controller + */ +struct ti_sci_sysreset_data { + const struct ti_sci_handle *sci; +}; + +static int ti_sci_sysreset_probe(struct udevice *dev) +{ + struct ti_sci_sysreset_data *data = dev_get_priv(dev); + + debug("%s(dev=%p)\n", __func__, dev); + + if (!data) + return -ENOMEM; + + /* Store handle for communication with the system controller */ + data->sci = ti_sci_get_handle(dev); + if (IS_ERR(data->sci)) + return PTR_ERR(data->sci); + + return 0; +} + +static int ti_sci_sysreset_request(struct udevice *dev, enum sysreset_t type) +{ + struct ti_sci_sysreset_data *data = dev_get_priv(dev); + const struct ti_sci_handle *sci = data->sci; + const struct ti_sci_core_ops *cops = &sci->ops.core_ops; + int ret; + + debug("%s(dev=%p, type=%d)\n", __func__, dev, type); + + ret = cops->reboot_device(sci); + if (ret) + dev_err(rst->dev, "%s: reboot_device failed (%d)\n", + __func__, ret); + + return ret; +} + +static struct sysreset_ops ti_sci_sysreset_ops = { + .request = ti_sci_sysreset_request, +}; + +static const struct udevice_id ti_sci_sysreset_of_match[] = { + { .compatible = "ti,sci-sysreset", }, + { /* sentinel */ }, +}; + +U_BOOT_DRIVER(ti_sci_sysreset) = { + .name = "ti-sci-sysreset", + .id = UCLASS_SYSRESET, + .of_match = ti_sci_sysreset_of_match, + .probe = ti_sci_sysreset_probe, + .priv_auto_alloc_size = sizeof(struct ti_sci_sysreset_data), + .ops = &ti_sci_sysreset_ops, +}; From patchwork Tue Aug 21 14:31:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960449 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtmR5mc9z9s5b for ; Wed, 22 Aug 2018 00:46:47 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 614DEC21E36; Tue, 21 Aug 2018 14:44:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 1FBFFC21EBB; Tue, 21 Aug 2018 14:37:16 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id C2CFDC21EE3; Tue, 21 Aug 2018 14:34:08 +0000 (UTC) Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) by lists.denx.de (Postfix) with ESMTPS id 2CB0FC21E1B for ; Tue, 21 Aug 2018 14:34:03 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEY10D044305; Tue, 21 Aug 2018 09:34:01 -0500 Received: from DLEE102.ent.ti.com (dlee102.ent.ti.com [157.170.170.32]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEY1s1019147; Tue, 21 Aug 2018 09:34:01 -0500 Received: from DLEE103.ent.ti.com (157.170.170.33) by DLEE102.ent.ti.com (157.170.170.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:34:01 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE103.ent.ti.com (157.170.170.33) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:34:01 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhc016556; Tue, 21 Aug 2018 09:33:59 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:55 +0530 Message-ID: <20180821143203.29142-18-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 17/25] mailbox: Allow attaching private data for mbox_chan X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" Sometimes mbox controllers wants to store private data in mbox_chan so that it can be used at a later point of time. Adding support for hooking private data. Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- include/mailbox.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/mailbox.h b/include/mailbox.h index c64951b2f7..93f4715e16 100644 --- a/include/mailbox.h +++ b/include/mailbox.h @@ -44,6 +44,7 @@ struct udevice; * * @dev: The device which implements the mailbox. * @id: The mailbox channel ID within the provider. + * @con_priv: Hook for controller driver to attach private data * * Currently, the mailbox API assumes that a single integer ID is enough to * identify and configure any mailbox channel for any mailbox provider. If this @@ -56,11 +57,9 @@ struct udevice; */ struct mbox_chan { struct udevice *dev; - /* - * Written by of_xlate. We assume a single id is enough for now. In the - * future, we might add more fields here. - */ + /* Written by of_xlate.*/ unsigned long id; + void *con_priv; }; /** From patchwork Tue Aug 21 14:31:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960462 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vttS2hBvz9s3x for ; Wed, 22 Aug 2018 00:52:00 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 1A318C21E15; Tue, 21 Aug 2018 14:47:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id C4A63C21E3A; Tue, 21 Aug 2018 14:39:20 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id D1858C21E88; Tue, 21 Aug 2018 14:34:13 +0000 (UTC) Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) by lists.denx.de (Postfix) with ESMTPS id 54D82C21E30 for ; Tue, 21 Aug 2018 14:34:05 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEY3Z1104793; Tue, 21 Aug 2018 09:34:03 -0500 Received: from DLEE101.ent.ti.com (dlee101.ent.ti.com [157.170.170.31]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEY3hY019534; Tue, 21 Aug 2018 09:34:03 -0500 Received: from DLEE104.ent.ti.com (157.170.170.34) by DLEE101.ent.ti.com (157.170.170.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:34:03 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE104.ent.ti.com (157.170.170.34) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:34:03 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhd016556; Tue, 21 Aug 2018 09:34:01 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:56 +0530 Message-ID: <20180821143203.29142-19-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 18/25] mailbox: Introduce K3 Secure Proxy Driver X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" Secure Proxy module manages hardware threads that are meant for communication between the processor entities. Adding support for this driver. Signed-off-by: Lokesh Vutla Signed-off-by: Andreas Dannenberg Reviewed-by: Tom Rini --- .../mailbox/k3-secure-proxy.txt | 40 ++ drivers/mailbox/Kconfig | 10 + drivers/mailbox/Makefile | 1 + drivers/mailbox/k3-sec-proxy.c | 438 ++++++++++++++++++ include/linux/soc/ti/k3-sec-proxy.h | 25 + 5 files changed, 514 insertions(+) create mode 100644 doc/device-tree-bindings/mailbox/k3-secure-proxy.txt create mode 100644 drivers/mailbox/k3-sec-proxy.c create mode 100644 include/linux/soc/ti/k3-sec-proxy.h diff --git a/doc/device-tree-bindings/mailbox/k3-secure-proxy.txt b/doc/device-tree-bindings/mailbox/k3-secure-proxy.txt new file mode 100644 index 0000000000..f3add0d4e7 --- /dev/null +++ b/doc/device-tree-bindings/mailbox/k3-secure-proxy.txt @@ -0,0 +1,40 @@ +Texas Instruments' K3 Secure Proxy +=================================== + +The Texas Instruments' K3 Secure Proxy is a mailbox controller that has +configurable threads maintained by System power processor. Each thread +has different address space that can be used to send or receive messages. + +Secure Proxy Device Node: +=========================== +Required properties: +-------------------- +- compatible: Shall be: "ti,am654-secure-proxy" +- reg-names data - Map the data region + scfg - Map the secure configuration region + rt - Map the Realtime region. +- reg: Contains the register map per reg-names. +- #mbox-cells Shall be 1. Contains the thread ID. + +Example: +-------- + +secproxy: secproxy@285b0000 { + compatible = "ti,am654-secure-proxy"; + reg = <0x2a380000 0x80000>, + <0x2a400000 0x80000>, + <0x2a480000 0x80000>; + reg-names = "rt", "scfg", "data"; + #mbox-cells = <1>; +}; + +client: + +systemcontroller: systemcontroller { + [...] + # RX thread ID is 4. + # TX thread ID is 5. + mboxes= <&secproxy 4>, + <&secproxy 5>; + [...] +}; diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index 9649b70589..2836ee4a7b 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -24,4 +24,14 @@ config TEGRA_HSP This enables support for the NVIDIA Tegra HSP Hw module, which implements doorbells, mailboxes, semaphores, and shared interrupts. +config K3_SEC_PROXY + bool "Texas Instruments K3 Secure Proxy Driver" + depends on DM_MAILBOX && ARCH_K3 + help + An implementation of Secure proxy slave driver for K3 SoCs from + Texas Instruments. Secure proxy is a communication entity mainly + used for communication between multiple processors with the SoC. + Select this driver if your platform has support for this hardware + block. + endmenu diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index 155dbeb099..4ac85d412f 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_DM_MAILBOX) += mailbox-uclass.o obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox.o obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox-test.o obj-$(CONFIG_TEGRA_HSP) += tegra-hsp.o +obj-$(CONFIG_K3_SEC_PROXY) += k3-sec-proxy.o diff --git a/drivers/mailbox/k3-sec-proxy.c b/drivers/mailbox/k3-sec-proxy.c new file mode 100644 index 0000000000..4654c8cb82 --- /dev/null +++ b/drivers/mailbox/k3-sec-proxy.c @@ -0,0 +1,438 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Texas Instruments' K3 Secure proxy Driver + * + * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Lokesh Vutla + */ + +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* SEC PROXY RT THREAD STATUS */ +#define RT_THREAD_STATUS 0x0 +#define RT_THREAD_THRESHOLD 0x4 +#define RT_THREAD_STATUS_ERROR_SHIFT 31 +#define RT_THREAD_STATUS_ERROR_MASK BIT(31) +#define RT_THREAD_STATUS_CUR_CNT_SHIFT 0 +#define RT_THREAD_STATUS_CUR_CNT_MASK GENMASK(7, 0) + +/* SEC PROXY SCFG THREAD CTRL */ +#define SCFG_THREAD_CTRL 0x1000 +#define SCFG_THREAD_CTRL_DIR_SHIFT 31 +#define SCFG_THREAD_CTRL_DIR_MASK BIT(31) + +#define SEC_PROXY_THREAD(base, x) ((base) + (0x1000 * (x))) +#define THREAD_IS_RX 1 +#define THREAD_IS_TX 0 + +/** + * struct k3_sec_proxy_desc - Description of secure proxy integration. + * @thread_count: Number of Threads. + * @max_msg_size: Message size in bytes. + * @data_start_offset: Offset of the First data register of the thread + * @data_end_offset: Offset of the Last data register of the thread + * @valid_threads: List of Valid threads that the processor can access + * @num_valid_threads: Number of valid threads. + */ +struct k3_sec_proxy_desc { + u16 thread_count; + u16 max_msg_size; + u16 data_start_offset; + u16 data_end_offset; + const u32 *valid_threads; + u32 num_valid_threads; +}; + +/** + * struct k3_sec_proxy_thread - Description of a secure proxy Thread + * @id: Thread ID + * @data: Thread Data path region for target + * @scfg: Secure Config Region for Thread + * @rt: RealTime Region for Thread + * @rx_buf: Receive buffer data, max message size. + */ +struct k3_sec_proxy_thread { + u32 id; + void __iomem *data; + void __iomem *scfg; + void __iomem *rt; + u32 *rx_buf; +}; + +/** + * struct k3_sec_proxy_mbox - Description of a Secure Proxy Instance + * @chan: Mailbox Channel + * @desc: Description of the SoC integration + * @chans: Array for valid thread instances + * @target_data: Secure Proxy region for Target Data + * @scfg: Secure Proxy Region for Secure configuration. + * @rt: Secure proxy Region for Real Time Region. + */ +struct k3_sec_proxy_mbox { + struct mbox_chan chan; + struct k3_sec_proxy_desc *desc; + struct k3_sec_proxy_thread *chans; + phys_addr_t target_data; + phys_addr_t scfg; + phys_addr_t rt; +}; + +static inline u32 sp_readl(void __iomem *addr, unsigned int offset) +{ + return readl(addr + offset); +} + +static inline void sp_writel(void __iomem *addr, unsigned int offset, u32 data) +{ + writel(data, addr + offset); +} + +/** + * k3_sec_proxy_of_xlate() - Translation of phandle to channel + * @chan: Mailbox channel + * @args: Phandle Pointer + * + * Translates the phandle args and fills up the Mailbox channel from client. + * Return: 0 if all goes good, else return corresponding error message. + */ +static int k3_sec_proxy_of_xlate(struct mbox_chan *chan, + struct ofnode_phandle_args *args) +{ + struct k3_sec_proxy_mbox *spm = dev_get_priv(chan->dev); + int ind, i; + + debug("%s(chan=%p)\n", __func__, chan); + + if (args->args_count != 1) { + debug("Invaild args_count: %d\n", args->args_count); + return -EINVAL; + } + ind = args->args[0]; + + for (i = 0; i < spm->desc->num_valid_threads; i++) + if (spm->chans[i].id == ind) { + chan->id = ind; + chan->con_priv = &spm->chans[i]; + return 0; + } + + dev_err(chan->dev, "%s: Invalid Thread ID %d\n", __func__, ind); + return -ENOENT; +} + +/** + * k3_sec_proxy_request() - Request for mailbox channel + * @chan: Channel Pointer + */ +static int k3_sec_proxy_request(struct mbox_chan *chan) +{ + debug("%s(chan=%p)\n", __func__, chan); + + return 0; +} + +/** + * k3_sec_proxy_free() - Free the mailbox channel + * @chan: Channel Pointer + */ +static int k3_sec_proxy_free(struct mbox_chan *chan) +{ + debug("%s(chan=%p)\n", __func__, chan); + + return 0; +} + +/** + * k3_sec_proxy_verify_thread() - Verify thread status before + * sending/receiving data. + * @spt: pointer to secure proxy thread description + * @dir: Direction of the thread + * + * Return: 0 if all goes good, else appropriate error message. + */ +static inline int k3_sec_proxy_verify_thread(struct k3_sec_proxy_thread *spt, + u8 dir) +{ + /* Check for any errors already available */ + if (sp_readl(spt->rt, RT_THREAD_STATUS) & + RT_THREAD_STATUS_ERROR_MASK) { + printf("%s: Thread %d is corrupted, cannot send data.\n", + __func__, spt->id); + return -EINVAL; + } + + /* Make sure thread is configured for right direction */ + if ((sp_readl(spt->scfg, SCFG_THREAD_CTRL) + & SCFG_THREAD_CTRL_DIR_MASK) >> SCFG_THREAD_CTRL_DIR_SHIFT != dir) { + if (dir) + printf("%s: Trying to receive data on tx Thread %d\n", + __func__, spt->id); + else + printf("%s: Trying to send data on rx Thread %d\n", + __func__, spt->id); + return -EINVAL; + } + + /* Check the message queue before sending/receiving data */ + if (!(sp_readl(spt->rt, RT_THREAD_STATUS) & + RT_THREAD_STATUS_CUR_CNT_MASK)) + return -ENODATA; + + return 0; +} + +/** + * k3_sec_proxy_send() - Send data via mailbox channel + * @chan: Channel Pointer + * @data: Pointer to k3_sec_proxy_msg + * + * Return: 0 if all goes good, else appropriate error message. + */ +static int k3_sec_proxy_send(struct mbox_chan *chan, const void *data) +{ + const struct k3_sec_proxy_msg *msg = (struct k3_sec_proxy_msg *)data; + struct k3_sec_proxy_mbox *spm = dev_get_priv(chan->dev); + struct k3_sec_proxy_thread *spt = chan->con_priv; + int num_words, trail_bytes, ret; + void __iomem *data_reg; + u32 *word_data; + + debug("%s(chan=%p, data=%p)\n", __func__, chan, data); + + ret = k3_sec_proxy_verify_thread(spt, THREAD_IS_TX); + if (ret) { + dev_err(dev, "%s: Thread%d verification failed. ret = %d\n", + __func__, spt->id, ret); + return ret; + } + + /* Check the message size. */ + if (msg->len > spm->desc->max_msg_size) { + printf("%s: Thread %ld message length %zu > max msg size %d\n", + __func__, chan->id, msg->len, spm->desc->max_msg_size); + return -EINVAL; + } + + /* Send the message */ + data_reg = spt->data + spm->desc->data_start_offset; + for (num_words = msg->len / sizeof(u32), word_data = (u32 *)msg->buf; + num_words; + num_words--, data_reg += sizeof(u32), word_data++) + writel(*word_data, data_reg); + + trail_bytes = msg->len % sizeof(u32); + if (trail_bytes) { + u32 data_trail = *word_data; + + /* Ensure all unused data is 0 */ + data_trail &= 0xFFFFFFFF >> (8 * (sizeof(u32) - trail_bytes)); + writel(data_trail, data_reg); + data_reg++; + } + + /* + * 'data_reg' indicates next register to write. If we did not already + * write on tx complete reg(last reg), we must do so for transmit + */ + if (data_reg <= (spt->data + spm->desc->data_end_offset)) + sp_writel(spt->data, spm->desc->data_end_offset, 0); + + debug("%s: Message successfully sent on thread %ld\n", + __func__, chan->id); + + return 0; +} + +/** + * k3_sec_proxy_recv() - Receive data via mailbox channel + * @chan: Channel Pointer + * @data: Pointer to k3_sec_proxy_msg + * + * Return: 0 if all goes good, else appropriate error message. + */ +static int k3_sec_proxy_recv(struct mbox_chan *chan, void *data) +{ + struct k3_sec_proxy_mbox *spm = dev_get_priv(chan->dev); + struct k3_sec_proxy_thread *spt = chan->con_priv; + struct k3_sec_proxy_msg *msg = data; + void __iomem *data_reg; + int num_words, ret; + u32 *word_data; + + debug("%s(chan=%p, data=%p)\n", __func__, chan, data); + + ret = k3_sec_proxy_verify_thread(spt, THREAD_IS_RX); + if (ret) + return ret; + + msg->len = spm->desc->max_msg_size; + msg->buf = spt->rx_buf; + data_reg = spt->data + spm->desc->data_start_offset; + word_data = spt->rx_buf; + for (num_words = spm->desc->max_msg_size / sizeof(u32); + num_words; + num_words--, data_reg += sizeof(u32), word_data++) + *word_data = readl(data_reg); + + debug("%s: Message successfully received from thread %ld\n", + __func__, chan->id); + + return 0; +} + +struct mbox_ops k3_sec_proxy_mbox_ops = { + .of_xlate = k3_sec_proxy_of_xlate, + .request = k3_sec_proxy_request, + .free = k3_sec_proxy_free, + .send = k3_sec_proxy_send, + .recv = k3_sec_proxy_recv, +}; + +/** + * k3_sec_proxy_of_to_priv() - generate private data from device tree + * @dev: corresponding k3 secure proxy device + * @spm: pointer to driver specific private data + * + * Return: 0 if all went ok, else corresponding error message. + */ +static int k3_sec_proxy_of_to_priv(struct udevice *dev, + struct k3_sec_proxy_mbox *spm) +{ + const void *blob = gd->fdt_blob; + + if (!blob) { + debug("'%s' no dt?\n", dev->name); + return -ENODEV; + } + + spm->target_data = devfdt_get_addr_name(dev, "target_data"); + if (spm->target_data == FDT_ADDR_T_NONE) { + dev_err(dev, "No reg property for target data base\n"); + return -EINVAL; + } + + spm->scfg = devfdt_get_addr_name(dev, "scfg"); + if (spm->rt == FDT_ADDR_T_NONE) { + dev_err(dev, "No reg property for Secure Cfg base\n"); + return -EINVAL; + } + + spm->rt = devfdt_get_addr_name(dev, "rt"); + if (spm->rt == FDT_ADDR_T_NONE) { + dev_err(dev, "No reg property for Real Time Cfg base\n"); + return -EINVAL; + } + + return 0; +} + +/** + * k3_sec_proxy_thread_setup - Initialize the parameters for all valid threads + * @spm: Mailbox instance for which threads needs to be initialized + * + * Return: 0 if all went ok, else corresponding error message + */ +static int k3_sec_proxy_thread_setup(struct k3_sec_proxy_mbox *spm) +{ + struct k3_sec_proxy_thread *spt; + int i, ind; + + for (i = 0; i < spm->desc->num_valid_threads; i++) { + spt = &spm->chans[i]; + ind = spm->desc->valid_threads[i]; + spt->id = ind; + spt->data = (void *)SEC_PROXY_THREAD(spm->target_data, ind); + spt->scfg = (void *)SEC_PROXY_THREAD(spm->scfg, ind); + spt->rt = (void *)SEC_PROXY_THREAD(spm->rt, ind); + spt->rx_buf = calloc(1, spm->desc->max_msg_size); + if (!spt->rx_buf) + return -ENOMEM; + } + + return 0; +} + +/** + * k3_sec_proxy_probe() - Basic probe + * @dev: corresponding mailbox device + * + * Return: 0 if all went ok, else corresponding error message + */ +static int k3_sec_proxy_probe(struct udevice *dev) +{ + struct k3_sec_proxy_mbox *spm = dev_get_priv(dev); + int ret; + + debug("%s(dev=%p)\n", __func__, dev); + + ret = k3_sec_proxy_of_to_priv(dev, spm); + if (ret) + return ret; + + spm->desc = (void *)dev_get_driver_data(dev); + spm->chans = calloc(spm->desc->num_valid_threads, + sizeof(struct k3_sec_proxy_thread)); + if (!spm->chans) + return -ENOMEM; + + ret = k3_sec_proxy_thread_setup(spm); + if (ret) { + debug("%s: secure proxy thread setup failed\n", __func__); + return ret; + } + + return 0; +} + +static int k3_sec_proxy_remove(struct udevice *dev) +{ + struct k3_sec_proxy_mbox *spm = dev_get_priv(dev); + + debug("%s(dev=%p)\n", __func__, dev); + + free(spm->chans); + + return 0; +} + +/* + * Thread ID #4: ROM request + * Thread ID #5: ROM response, SYSFW notify + * Thread ID #6: SYSFW request response + * Thread ID #7: SYSFW request high priority + * Thread ID #8: SYSFW request low priority + * Thread ID #9: SYSFW notify response + */ +static const u32 am6x_valid_threads[] = { 4, 5, 6, 7, 8, 9, 11, 13 }; + +static const struct k3_sec_proxy_desc am654_desc = { + .thread_count = 90, + .max_msg_size = 60, + .data_start_offset = 0x4, + .data_end_offset = 0x3C, + .valid_threads = am6x_valid_threads, + .num_valid_threads = ARRAY_SIZE(am6x_valid_threads), +}; + +static const struct udevice_id k3_sec_proxy_ids[] = { + { .compatible = "ti,am654-secure-proxy", .data = (ulong)&am654_desc}, + { } +}; + +U_BOOT_DRIVER(k3_sec_proxy) = { + .name = "k3-secure-proxy", + .id = UCLASS_MAILBOX, + .of_match = k3_sec_proxy_ids, + .probe = k3_sec_proxy_probe, + .remove = k3_sec_proxy_remove, + .priv_auto_alloc_size = sizeof(struct k3_sec_proxy_mbox), + .ops = &k3_sec_proxy_mbox_ops, +}; diff --git a/include/linux/soc/ti/k3-sec-proxy.h b/include/linux/soc/ti/k3-sec-proxy.h new file mode 100644 index 0000000000..ac83f72742 --- /dev/null +++ b/include/linux/soc/ti/k3-sec-proxy.h @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Texas Instruments' K3 Secure proxy + * + * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Lokesh Vutla + * + */ + +#ifndef K3_SEC_PROXY_H +#define K3_SEC_PROXY_H + +/** + * struct k3_sec_proxy_msg - Secure proxy message structure + * @len: Length of data in the Buffer + * @buf: Buffer pointer + * + * This is the structure for data used in mbox_send() and mbox_recv(). + */ +struct k3_sec_proxy_msg { + size_t len; + u32 *buf; +}; + +#endif /* K3_SEC_PROXY_H */ From patchwork Tue Aug 21 14:31:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960466 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtvC19Cjz9s3x for ; Wed, 22 Aug 2018 00:52:39 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id C6FBBC21E30; Tue, 21 Aug 2018 14:47:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 3362BC21ECF; Tue, 21 Aug 2018 14:38:45 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 1EB21C21E62; Tue, 21 Aug 2018 14:34:13 +0000 (UTC) Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) by lists.denx.de (Postfix) with ESMTPS id B8CFDC21E2C for ; Tue, 21 Aug 2018 14:34:07 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEY53R044363; Tue, 21 Aug 2018 09:34:05 -0500 Received: from DFLE102.ent.ti.com (dfle102.ent.ti.com [10.64.6.23]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEY595019627; Tue, 21 Aug 2018 09:34:05 -0500 Received: from DFLE114.ent.ti.com (10.64.6.35) by DFLE102.ent.ti.com (10.64.6.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:34:05 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE114.ent.ti.com (10.64.6.35) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:34:05 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhe016556; Tue, 21 Aug 2018 09:34:03 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:57 +0530 Message-ID: <20180821143203.29142-20-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 19/25] spl: Allow mailbox drivers to be used within SPL X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" Add an option for building mailbox drivers within SPL. Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- common/spl/Kconfig | 8 ++++++++ drivers/Makefile | 1 + drivers/mailbox/Makefile | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 11c2c0133f..67275eb39d 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -430,6 +430,14 @@ config SPL_LIBGENERIC_SUPPORT boards. Enable this option to build the code in lib/ as part of an SPL build. +config SPL_DM_MAILBOX + bool "Support Mailbox" + help + Enable support for Mailbox within SPL. This enable the inter + processor communication protocols tobe used within SPL. Enable + this option to build the drivers in drivers/mailbox as part of + SPL build. + config SPL_MMC_SUPPORT bool "Support MMC" depends on MMC diff --git a/drivers/Makefile b/drivers/Makefile index d296354b3c..c0124765db 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_$(SPL_TPL_)SERIAL_SUPPORT) += serial/ obj-$(CONFIG_$(SPL_TPL_)SPI_FLASH_SUPPORT) += mtd/spi/ obj-$(CONFIG_$(SPL_TPL_)SPI_SUPPORT) += spi/ obj-$(CONFIG_$(SPL_TPL_)TIMER) += timer/ +obj-$(CONFIG_$(SPL_)DM_MAILBOX) += mailbox/ ifndef CONFIG_TPL_BUILD ifdef CONFIG_SPL_BUILD diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index 4ac85d412f..243ff6f3ce 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_DM_MAILBOX) += mailbox-uclass.o +obj-$(CONFIG_$(SPL_)DM_MAILBOX) += mailbox-uclass.o obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox.o obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox-test.o obj-$(CONFIG_TEGRA_HSP) += tegra-hsp.o From patchwork Tue Aug 21 14:31:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960468 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="dpsKnvNB"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtvy0Gsfz9s3x for ; Wed, 22 Aug 2018 00:53:17 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id B391DC21E2F; Tue, 21 Aug 2018 14:48:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 41F7AC21E34; Tue, 21 Aug 2018 14:40:10 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id E3FDFC21E2C; Tue, 21 Aug 2018 14:34:17 +0000 (UTC) Received: from lelv0143.ext.ti.com (lelv0143.ext.ti.com [198.47.23.248]) by lists.denx.de (Postfix) with ESMTPS id 817B8C21E56 for ; Tue, 21 Aug 2018 14:34:10 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEY9P9128171; Tue, 21 Aug 2018 09:34:09 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1534862049; bh=gEYI3L5NRWao4isJ5wK2aIC06xORY+ha/w07ZpysFMA=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=dpsKnvNBvX2J6/JLZw/EqJopUmGwOuOGt0afKI6xNCmOzcUAXHitHVZTip19qCUUB tTEqTTi28bWcqm6LeMK5K+R7IxLO+s7GoCA1fa8K2IeCFyQkyNAAkQwnoedz8u//eG fWC3uNIaOSMsjaGEONtJl/6CWnT//M/B+397QTZg= Received: from DLEE100.ent.ti.com (dlee100.ent.ti.com [157.170.170.30]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEY9XW019747; Tue, 21 Aug 2018 09:34:09 -0500 Received: from DLEE115.ent.ti.com (157.170.170.26) by DLEE100.ent.ti.com (157.170.170.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:34:07 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE115.ent.ti.com (157.170.170.26) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:34:07 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhf016556; Tue, 21 Aug 2018 09:34:06 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:58 +0530 Message-ID: <20180821143203.29142-21-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 20/25] remoteproc: Allow for individual remoteproc initialization X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" Existing rproc_init() api tries to initialize all available remoteproc devices. This will fail when there is dependency among available remoteprocs. So introduce a separate api that allows to initialize remoteprocs individually based on id. Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- drivers/remoteproc/rproc-uclass.c | 19 +++++++++++++++++++ include/remoteproc.h | 9 +++++++++ 2 files changed, 28 insertions(+) diff --git a/drivers/remoteproc/rproc-uclass.c b/drivers/remoteproc/rproc-uclass.c index 1fc3d424b3..c8a41a6332 100644 --- a/drivers/remoteproc/rproc-uclass.c +++ b/drivers/remoteproc/rproc-uclass.c @@ -272,6 +272,25 @@ int rproc_init(void) return ret; } +int rproc_dev_init(int id) +{ + struct udevice *dev = NULL; + int ret; + + ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev); + if (ret) { + debug("Unknown remote processor id '%d' requested(%d)\n", + id, ret); + return ret; + } + + ret = device_probe(dev); + if (ret) + debug("%s: Failed to initialize - %d\n", dev->name, ret); + + return ret; +} + int rproc_load(int id, ulong addr, ulong size) { struct udevice *dev = NULL; diff --git a/include/remoteproc.h b/include/remoteproc.h index c3c3f46a1a..a59dba8481 100644 --- a/include/remoteproc.h +++ b/include/remoteproc.h @@ -85,6 +85,14 @@ struct dm_rproc_ops { */ int rproc_init(void); +/** + * rproc_dev_init() - Initialize a remote proc device based on id + * @id: id of the remote processor + * + * Return: 0 if all ok, else appropriate error value. + */ +int rproc_dev_init(int id); + /** * rproc_is_initialized() - check to see if remoteproc devices are initialized * @@ -150,6 +158,7 @@ int rproc_ping(int id); int rproc_is_running(int id); #else static inline int rproc_init(void) { return -ENOSYS; } +static inline int rproc_dev_init(int id) { return -ENOSYS; } static inline bool rproc_is_initialized(void) { return false; } static inline int rproc_load(int id, ulong addr, ulong size) { return -ENOSYS; } static inline int rproc_start(int id) { return -ENOSYS; } From patchwork Tue Aug 21 14:31:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960479 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vv2F4Drzz9s3x for ; Wed, 22 Aug 2018 00:58:45 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 3F277C21E39; Tue, 21 Aug 2018 14:49:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id BA19BC21E7D; Tue, 21 Aug 2018 14:41:05 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id DF6B0C21E35; Tue, 21 Aug 2018 14:34:19 +0000 (UTC) Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) by lists.denx.de (Postfix) with ESMTPS id EF35BC21E75 for ; Tue, 21 Aug 2018 14:34:12 +0000 (UTC) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEYB9F104830; Tue, 21 Aug 2018 09:34:11 -0500 Received: from DLEE107.ent.ti.com (dlee107.ent.ti.com [157.170.170.37]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEYBFw012138; Tue, 21 Aug 2018 09:34:11 -0500 Received: from DLEE105.ent.ti.com (157.170.170.35) by DLEE107.ent.ti.com (157.170.170.37) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:34:10 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE105.ent.ti.com (157.170.170.35) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:34:09 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhg016556; Tue, 21 Aug 2018 09:34:08 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:01:59 +0530 Message-ID: <20180821143203.29142-22-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 21/25] remoteproc: Introduce K3 system controller X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" K3 specific SoCs have a dedicated microcontroller for doing resource management. Any HLOS/firmware on compute clusters should load a firmware to this microcontroller before accessing any resource. Adding support for loading this firmware. After the K3 system controller got loaded with firmware and started up it sends out a boot notification message through the secure proxy facility using the TI SCI protocol. Intercept and receive this message through the rproc start operation which will need to get invoked explicitly after the firmware got loaded. Signed-off-by: Lokesh Vutla Signed-off-by: Andreas Dannenberg --- .../remoteproc/k3-system-controller.txt | 24 ++ drivers/remoteproc/Kconfig | 9 + drivers/remoteproc/Makefile | 1 + drivers/remoteproc/k3_system_controller.c | 323 ++++++++++++++++++ 4 files changed, 357 insertions(+) create mode 100644 doc/device-tree-bindings/remoteproc/k3-system-controller.txt create mode 100644 drivers/remoteproc/k3_system_controller.c diff --git a/doc/device-tree-bindings/remoteproc/k3-system-controller.txt b/doc/device-tree-bindings/remoteproc/k3-system-controller.txt new file mode 100644 index 0000000000..32f4720b0d --- /dev/null +++ b/doc/device-tree-bindings/remoteproc/k3-system-controller.txt @@ -0,0 +1,24 @@ +Texas Instruments' K3 System Controller +========================================= + +K3 specific SoCs have a dedicated microcontroller for doing +resource management. Any HLOS/firmware on compute clusters should +load a firmware to this microcontroller before accessing any resource. +This driver communicates with ROM for loading this firmware. + +Required properties: +-------------------- +- compatible: Shall be: "ti,am654-system-controller" +- mbox-names: "tx" for Transfer channel + "rx" for Receive channel +- mboxes: Corresponding phandles to mailbox channels. + + +Example: +-------- + +system-controller: system-controller { + compatible = "ti,am654-system-controller"; + mboxes= <&secproxy 4>, <&secproxy 5>; + mbox-names = "tx", "rx"; +}; diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index becae5f85d..812d30153b 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -13,6 +13,15 @@ config REMOTEPROC depends on DM # Please keep the configuration alphabetically sorted. +config K3_SYSTEM_CONTROLLER + bool "Support for TI' K3 System Controller" + select REMOTEPROC + depends on DM + depends on ARCH_K3 + depends on OF_CONTROL + help + Say 'y' here to add support for TI' K3 System Controller. + config REMOTEPROC_SANDBOX bool "Support for Test processor for Sandbox" select REMOTEPROC diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile index bda995e21b..bfd02ad52d 100644 --- a/drivers/remoteproc/Makefile +++ b/drivers/remoteproc/Makefile @@ -7,5 +7,6 @@ obj-$(CONFIG_REMOTEPROC) += rproc-uclass.o # Remote proc drivers - Please keep this list alphabetically sorted. +obj-$(CONFIG_K3_SYSTEM_CONTROLLER) += k3_system_controller.o obj-$(CONFIG_REMOTEPROC_SANDBOX) += sandbox_testproc.o obj-$(CONFIG_REMOTEPROC_TI_POWER) += ti_power_proc.o diff --git a/drivers/remoteproc/k3_system_controller.c b/drivers/remoteproc/k3_system_controller.c new file mode 100644 index 0000000000..3c316a1234 --- /dev/null +++ b/drivers/remoteproc/k3_system_controller.c @@ -0,0 +1,323 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Texas Instruments' K3 System Controller Driver + * + * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Lokesh Vutla + */ + +#include +#include +#include +#include +#include +#include + +#define K3_MSG_R5_TO_M3_M3FW 0x8105 +#define K3_MSG_M3_TO_R5_CERT_RESULT 0x8805 +#define K3_MSG_M3_TO_R5_BOOT_NOTIFICATION 0x000A + +#define K3_FLAGS_MSG_CERT_AUTH_PASS 0x555555 +#define K3_FLAGS_MSG_CERT_AUTH_FAIL 0xffffff + +/** + * struct k3_sysctrler_msg_hdr - Generic Header for Messages and responses. + * @cmd_id: Message ID. One of K3_MSG_* + * @host_id: Host ID of the message + * @seq_ne: Message identifier indicating a transfer sequence. + * @flags: Flags for the message. + */ +struct k3_sysctrler_msg_hdr { + u16 cmd_id; + u8 host_id; + u8 seq_nr; + u32 flags; +} __attribute__ ((__packed__)); + +/** + * struct k3_sysctrler_load_msg - Message format for Firmware loading + * @hdr: Generic message hdr + * @buffer_address: Address at which firmware is located. + * @buffer_size: Size of the firmware. + */ +struct k3_sysctrler_load_msg { + struct k3_sysctrler_msg_hdr hdr; + u32 buffer_address; + u32 buffer_size; +} __attribute__ ((__packed__)); + +/** + * struct k3_sysctrler_boot_notification_msg - Message format for boot + * notification + * @checksum: Checksum for the entire message + * @reserved: Reserved for future use. + * @hdr: Generic message hdr + */ +struct k3_sysctrler_boot_notification_msg { + u16 checksum; + u16 reserved; + struct k3_sysctrler_msg_hdr hdr; +} __attribute__ ((__packed__)); + +/** + * struct k3_sysctrler_desc - Description of SoC integration. + * @host_id: Host identifier representing the compute entity + * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds) + * @max_msg_size: Maximum size of data per message that can be handled. + */ +struct k3_sysctrler_desc { + u8 host_id; + int max_rx_timeout_us; + int max_msg_size; +}; + +/** + * struct k3_sysctrler_privdata - Structure representing System Controller data. + * @chan_tx: Transmit mailbox channel + * @chan_rx: Receive mailbox channel + * @desc: SoC description for this instance + * @seq_nr: Counter for number of messages sent. + */ +struct k3_sysctrler_privdata { + struct mbox_chan chan_tx; + struct mbox_chan chan_rx; + struct k3_sysctrler_desc *desc; + u32 seq_nr; +}; + +static inline +void k3_sysctrler_load_msg_setup(struct k3_sysctrler_load_msg *fw, + struct k3_sysctrler_privdata *priv, + ulong addr, ulong size) +{ + fw->hdr.cmd_id = K3_MSG_R5_TO_M3_M3FW; + fw->hdr.host_id = priv->desc->host_id; + fw->hdr.seq_nr = priv->seq_nr++; + fw->hdr.flags = 0x0; + fw->buffer_address = addr; + fw->buffer_size = size; +} + +static int k3_sysctrler_load_response(u32 *buf) +{ + struct k3_sysctrler_load_msg *fw; + + fw = (struct k3_sysctrler_load_msg *)buf; + + /* Check for proper response ID */ + if (fw->hdr.cmd_id != K3_MSG_M3_TO_R5_CERT_RESULT) { + dev_err(dev, "%s: Command expected 0x%x, but received 0x%x\n", + __func__, K3_MSG_M3_TO_R5_CERT_RESULT, fw->hdr.cmd_id); + return -EINVAL; + } + + /* Check for certificate authentication result */ + if (fw->hdr.flags == K3_FLAGS_MSG_CERT_AUTH_FAIL) { + dev_err(dev, "%s: Firmware certificate authentication failed\n", + __func__); + return -EINVAL; + } else if (fw->hdr.flags != K3_FLAGS_MSG_CERT_AUTH_PASS) { + dev_err(dev, "%s: Firmware Load response Invalid %d\n", + __func__, fw->hdr.flags); + return -EINVAL; + } + + debug("%s: Firmware authentication passed\n", __func__); + + return 0; +} + +static int k3_sysctrler_boot_notification_response(u32 *buf) +{ + struct k3_sysctrler_boot_notification_msg *boot; + + boot = (struct k3_sysctrler_boot_notification_msg *)buf; + + /* ToDo: Verify checksum */ + + /* Check for proper response ID */ + if (boot->hdr.cmd_id != K3_MSG_M3_TO_R5_BOOT_NOTIFICATION) { + dev_err(dev, "%s: Command expected 0x%x, but received 0x%x\n", + __func__, K3_MSG_M3_TO_R5_BOOT_NOTIFICATION, + boot->hdr.cmd_id); + return -EINVAL; + } + + debug("%s: Boot notification received\n", __func__); + + return 0; +} + +/** + * k3_sysctrler_load() - Loadup the K3 remote processor + * @dev: corresponding K3 remote processor device + * @addr: Address in memory where image binary is stored + * @size: Size in bytes of the image binary + * + * Return: 0 if all goes good, else appropriate error message. + */ +static int k3_sysctrler_load(struct udevice *dev, ulong addr, ulong size) +{ + struct k3_sysctrler_privdata *priv = dev_get_priv(dev); + struct k3_sysctrler_load_msg firmware; + struct k3_sec_proxy_msg msg; + int ret; + + debug("%s: Loading binary from 0x%08lX, size 0x%08lX\n", + __func__, addr, size); + + memset(&firmware, 0, sizeof(firmware)); + memset(&msg, 0, sizeof(msg)); + + /* Setup the message */ + k3_sysctrler_load_msg_setup(&firmware, priv, addr, size); + msg.len = sizeof(firmware); + msg.buf = (u32 *)&firmware; + + /* Send the message */ + ret = mbox_send(&priv->chan_tx, &msg); + if (ret) { + dev_err(dev, "%s: Firmware Loading failed. ret = %d\n", + __func__, ret); + return ret; + } + + /* Receive the response */ + ret = mbox_recv(&priv->chan_rx, &msg, priv->desc->max_rx_timeout_us); + if (ret) { + dev_err(dev, "%s: Firmware Load response failed. ret = %d\n", + __func__, ret); + return ret; + } + + /* Process the response */ + ret = k3_sysctrler_load_response(msg.buf); + if (ret) + return ret; + + debug("%s: Firmware Loaded successfully on dev %s\n", + __func__, dev->name); + + return 0; +} + +/** + * k3_sysctrler_start() - Start the remote processor + * Note that while technically the K3 system controller starts up + * automatically after its firmware got loaded we still want to + * utilize the rproc start operation for other startup-related + * tasks. + * @dev: device to operate upon + * + * Return: 0 if all went ok, else return appropriate error + */ +static int k3_sysctrler_start(struct udevice *dev) +{ + struct k3_sysctrler_privdata *priv = dev_get_priv(dev); + struct k3_sec_proxy_msg msg; + int ret; + + debug("%s(dev=%p)\n", __func__, dev); + + /* Receive the boot notification. Note that it is sent only once. */ + ret = mbox_recv(&priv->chan_rx, &msg, priv->desc->max_rx_timeout_us); + if (ret) { + dev_err(dev, "%s: Boot Notification response failed. ret = %d\n", + __func__, ret); + return ret; + } + + /* Process the response */ + ret = k3_sysctrler_boot_notification_response(msg.buf); + if (ret) + return ret; + + debug("%s: Boot notification received successfully on dev %s\n", + __func__, dev->name); + + return 0; +} + +static const struct dm_rproc_ops k3_sysctrler_ops = { + .load = k3_sysctrler_load, + .start = k3_sysctrler_start, +}; + +/** + * k3_of_to_priv() - generate private data from device tree + * @dev: corresponding k3 remote processor device + * @priv: pointer to driver specific private data + * + * Return: 0 if all goes good, else appropriate error message. + */ +static int k3_of_to_priv(struct udevice *dev, + struct k3_sysctrler_privdata *priv) +{ + int ret; + + ret = mbox_get_by_name(dev, "tx", &priv->chan_tx); + if (ret) { + dev_err(dev, "%s: Acquiring Tx channel failed. ret = %d\n", + __func__, ret); + return ret; + } + + ret = mbox_get_by_name(dev, "rx", &priv->chan_rx); + if (ret) { + dev_err(dev, "%s: Acquiring Rx channel failed. ret = %d\n", + __func__, ret); + return ret; + } + + return 0; +} + +/** + * k3_sysctrler_probe() - Basic probe + * @dev: corresponding k3 remote processor device + * + * Return: 0 if all goes good, else appropriate error message. + */ +static int k3_sysctrler_probe(struct udevice *dev) +{ + struct k3_sysctrler_privdata *priv; + int ret; + + debug("%s(dev=%p)\n", __func__, dev); + + priv = dev_get_priv(dev); + + ret = k3_of_to_priv(dev, priv); + if (ret) { + dev_err(dev, "%s: Probe failed with error %d\n", __func__, ret); + return ret; + } + + priv->desc = (void *)dev_get_driver_data(dev); + priv->seq_nr = 0; + + return 0; +} + +static const struct k3_sysctrler_desc k3_sysctrler_am654_desc = { + .host_id = 4, /* HOST_ID_R5_1 */ + .max_rx_timeout_us = 400000, + .max_msg_size = 60, +}; + +static const struct udevice_id k3_sysctrler_ids[] = { + { + .compatible = "ti,am654-system-controller", + .data = (ulong)&k3_sysctrler_am654_desc, + }, + {} +}; + +U_BOOT_DRIVER(k3_sysctrler) = { + .name = "k3_system_controller", + .of_match = k3_sysctrler_ids, + .id = UCLASS_REMOTEPROC, + .ops = &k3_sysctrler_ops, + .probe = k3_sysctrler_probe, + .priv_auto_alloc_size = sizeof(struct k3_sysctrler_privdata), +}; From patchwork Tue Aug 21 14:32:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960469 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="XUiS8DD2"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtwJ63chz9s5b for ; Wed, 22 Aug 2018 00:53:36 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 87B15C21E4E; Tue, 21 Aug 2018 14:48:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id B98E2C21E88; Tue, 21 Aug 2018 14:39:25 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 9A059C21DFB; Tue, 21 Aug 2018 14:34:20 +0000 (UTC) Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) by lists.denx.de (Postfix) with ESMTPS id DF177C21E4F for ; Tue, 21 Aug 2018 14:34:13 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEYCEi116147; Tue, 21 Aug 2018 09:34:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1534862052; bh=FnJseks8OkOTvygXy3eR+YFVqAijXUzoc6VeP20AARM=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=XUiS8DD2Vzd7Z3mnOLliVCr3O/sVx4cEMqiSXQ/vwtPtnyzI4TwQgE5se3emX4gWE +RX4WQmj+kr/rOCk1q++wXH5WxJhC3yk2Oi34oJGAgd20Sst72b1fvFku0vBO9Bxn1 up0lzK+IY+yF01ufbUWxyG1GI4spn2sNlMR50K9c= Received: from DLEE100.ent.ti.com (dlee100.ent.ti.com [157.170.170.30]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEYCjg019837; Tue, 21 Aug 2018 09:34:12 -0500 Received: from DLEE102.ent.ti.com (157.170.170.32) by DLEE100.ent.ti.com (157.170.170.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:34:12 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE102.ent.ti.com (157.170.170.32) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:34:12 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhh016556; Tue, 21 Aug 2018 09:34:10 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:02:00 +0530 Message-ID: <20180821143203.29142-23-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 22/25] remoteproc: Introduce K3 remoteproc driver X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" Add support for K3 based remoteproc driver that communicates with TISCI to start start a remote processor. Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- .../remoteproc/k3-rproc.txt | 50 ++++ drivers/remoteproc/Kconfig | 9 + drivers/remoteproc/Makefile | 1 + drivers/remoteproc/k3_rproc.c | 244 ++++++++++++++++++ 4 files changed, 304 insertions(+) create mode 100644 doc/device-tree-bindings/remoteproc/k3-rproc.txt create mode 100644 drivers/remoteproc/k3_rproc.c diff --git a/doc/device-tree-bindings/remoteproc/k3-rproc.txt b/doc/device-tree-bindings/remoteproc/k3-rproc.txt new file mode 100644 index 0000000000..0a1e858225 --- /dev/null +++ b/doc/device-tree-bindings/remoteproc/k3-rproc.txt @@ -0,0 +1,50 @@ +Texas Instruments' K3 Remote processor driver +============================================= + +In K3 generation Socs, loading an image on any processing entity +cannot be done directly from U-Boot. In order to load an image, +remoteproc driver should communicate to SYSFW with a specific sequence. +Also enable the timer required for this remotecore. + +Required properties: +-------------------- +- compatible: Shall be: "ti,am654-rproc" +- reg: base address of the remoteproc timer. +- power-domains: Should contain two sets of entries: + First set corresponds to pm domain of the + remotecore timer. Seconf entry corresponds to the + remoteproc to start. + This property is as per the binding, + doc/device-tree-bindings/power/ti,sci-pm-domain.txt +- resets: Should contain a phandle to a reset controller node + and an args specifier containing the remote code + device id and reset mask value. This is as per the + doc/device-tree-bindings/reset/ti,sci-reset.txt +- ti,sci: Phandle to TI-SCI compatible System controller node. +- ti,sci-proc-id: Processor id as identified by TISCI + +Optional properties: +-------------------- +- assigned-clocks: Should contain a phandle to clock node and an args + specifier containing the remote core device id and + the clock id within the remote core. This is as per + doc/device-tree-bindings/clock/ti,sci-clk.txt +- assigned-clock-rates: One entry for each entry of assigned-clocks. This is + the frequency at which the corresponding clock needs + to be assigned. +- ti,sci-host-id: Host ID to which the processor control is transferred to + +Example: +--------- + +a53_0: a53@0 { + compatible = "ti,am654-rproc"; + power-domains = <&k3_pds 61>, + <&k3_pds 202>; + resets = <&k3_reset 202 0>; + assigned-clocks = <&k3_clks 202 0>; + assigned-clock-rates = <800000000>; + ti,sci = <&dmsc>; + ti,sci-proc-id = <32>; + ti,sci-host-id = <10>; +}; diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 812d30153b..9eb532bc7a 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -22,6 +22,15 @@ config K3_SYSTEM_CONTROLLER help Say 'y' here to add support for TI' K3 System Controller. +config REMOTEPROC_K3 + bool "Support for TI's K3 based remoteproc driver" + select REMOTEPROC + depends on DM + depends on ARCH_K3 + depends on OF_CONTROL + help + Say 'y' here to add support for TI' K3 remoteproc driver. + config REMOTEPROC_SANDBOX bool "Support for Test processor for Sandbox" select REMOTEPROC diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile index bfd02ad52d..87ef9e61a7 100644 --- a/drivers/remoteproc/Makefile +++ b/drivers/remoteproc/Makefile @@ -8,5 +8,6 @@ obj-$(CONFIG_REMOTEPROC) += rproc-uclass.o # Remote proc drivers - Please keep this list alphabetically sorted. obj-$(CONFIG_K3_SYSTEM_CONTROLLER) += k3_system_controller.o +obj-$(CONFIG_REMOTEPROC_K3) += k3_rproc.o obj-$(CONFIG_REMOTEPROC_SANDBOX) += sandbox_testproc.o obj-$(CONFIG_REMOTEPROC_TI_POWER) += ti_power_proc.o diff --git a/drivers/remoteproc/k3_rproc.c b/drivers/remoteproc/k3_rproc.c new file mode 100644 index 0000000000..4028d4aa66 --- /dev/null +++ b/drivers/remoteproc/k3_rproc.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Texas Instruments' K3 Remoteproc driver + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Lokesh Vutla + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define INVALID_ID 0xffff + +#define GTC_CNTCR_REG 0x0 +#define GTC_CNTR_EN 0x3 + +/** + * struct k3_rproc_privdata - Structure representing Remote processor data. + * @rproc_pwrdmn: rproc power domain data + * @rproc_rst: rproc reset control data + * @sci: Pointer to TISCI handle + * @gtc_base: Timer base address. + * @proc_id: TISCI processor ID + * @host_id: TISCI host id to which the processor gets assigned to. + */ +struct k3_rproc_privdata { + struct power_domain rproc_pwrdmn; + struct power_domain gtc_pwrdmn; + struct reset_ctl rproc_rst; + const struct ti_sci_handle *sci; + void *gtc_base; + u16 proc_id; + u16 host_id; +}; + +/** + * k3_rproc_load() - Load up the Remote processor image + * @dev: rproc device pointer + * @addr: Address at which image is available + * @size: size of the image + * + * Return: 0 if all goes good, else appropriate error message. + */ +static int k3_rproc_load(struct udevice *dev, ulong addr, ulong size) +{ + struct k3_rproc_privdata *rproc = dev_get_priv(dev); + const struct ti_sci_proc_ops *pops = &rproc->sci->ops.proc_ops; + int ret; + + dev_dbg(dev, "%s addr = 0x%lx, size = 0x%lx\n", __func__, addr, size); + + /* request for the processor */ + ret = pops->proc_request(rproc->sci, rproc->proc_id); + if (ret) { + dev_err(dev, "Requesting processor failed %d\n", ret); + return ret; + } + + ret = pops->set_proc_boot_cfg(rproc->sci, rproc->proc_id, addr, 0, 0); + if (ret) { + dev_err(dev, "set_proc_boot_cfg failed %d\n", ret); + return ret; + } + + dev_dbg(dev, "%s: rproc successfully loaded\n", __func__); + + return 0; +} + +/** + * k3_rproc_start() - Start the remote processor + * @dev: rproc device pointer + * + * Return: 0 if all went ok, else return appropriate error + */ +static int k3_rproc_start(struct udevice *dev) +{ + struct k3_rproc_privdata *rproc = dev_get_priv(dev); + const struct ti_sci_proc_ops *pops = &rproc->sci->ops.proc_ops; + int ret; + + dev_dbg(dev, "%s\n", __func__); + + ret = power_domain_on(&rproc->gtc_pwrdmn); + if (ret) { + dev_err(dev, "power_domain_on() failed: %d\n", ret); + return ret; + } + + /* Enable the timer before starting remote core */ + writel(GTC_CNTR_EN, rproc->gtc_base + GTC_CNTCR_REG); + + /* + * Setting the right clock frequency would have taken care by + * assigned-clock-rates during the device probe. So no need to + * set the frequency again here. + */ + ret = power_domain_on(&rproc->rproc_pwrdmn); + if (ret) { + dev_err(dev, "power_domain_on() failed: %d\n", ret); + return ret; + } + + if (rproc->host_id != INVALID_ID) { + ret = pops->proc_handover(rproc->sci, rproc->proc_id, + rproc->host_id); + if (ret) { + dev_err(dev, "Handover processor failed %d\n", ret); + return ret; + } + } else { + ret = pops->proc_release(rproc->sci, rproc->proc_id); + if (ret) { + dev_err(dev, "Processor release failed %d\n", ret); + return ret; + } + } + + dev_dbg(dev, "%s: rproc successfully started\n", __func__); + + return 0; +} + +/** + * k3_rproc_init() - Initialize the remote processor + * @dev: rproc device pointer + * + * Return: 0 if all went ok, else return appropriate error + */ +static int k3_rproc_init(struct udevice *dev) +{ + dev_dbg(dev, "%s\n", __func__); + + /* Enable the module */ + dev_dbg(dev, "%s: rproc successfully initialized\n", __func__); + + return 0; +} + +static const struct dm_rproc_ops k3_rproc_ops = { + .init = k3_rproc_init, + .load = k3_rproc_load, + .start = k3_rproc_start, +}; + +/** + * k3_of_to_priv() - generate private data from device tree + * @dev: corresponding k3 remote processor device + * @priv: pointer to driver specific private data + * + * Return: 0 if all goes good, else appropriate error message. + */ +static int k3_rproc_of_to_priv(struct udevice *dev, + struct k3_rproc_privdata *rproc) +{ + int ret; + + dev_dbg(dev, "%s\n", __func__); + + ret = power_domain_get_by_index(dev, &rproc->rproc_pwrdmn, 1); + if (ret) { + dev_err(dev, "power_domain_get() failed: %d\n", ret); + return ret; + } + + ret = power_domain_get_by_index(dev, &rproc->gtc_pwrdmn, 0); + if (ret) { + dev_err(dev, "power_domain_get() failed: %d\n", ret); + return ret; + } + + ret = reset_get_by_index(dev, 0, &rproc->rproc_rst); + if (ret) { + dev_err(dev, "reset_get() failed: %d\n", ret); + return ret; + } + + rproc->sci = ti_sci_get_by_phandle(dev, "ti,sci"); + if (IS_ERR(rproc->sci)) { + dev_err(dev, "ti_sci get failed: %d\n", ret); + return PTR_ERR(rproc->sci); + } + + rproc->gtc_base = dev_read_addr_ptr(dev); + if (!rproc->gtc_base) { + dev_err(dev, "Get address failed\n"); + return -ENODEV; + } + + rproc->proc_id = dev_read_u32_default(dev, "ti,sci-proc-id", + INVALID_ID); + rproc->host_id = dev_read_u32_default(dev, "ti,sci-host-id", + INVALID_ID); + + return 0; +} + +/** + * k3_rproc_probe() - Basic probe + * @dev: corresponding k3 remote processor device + * + * Return: 0 if all goes good, else appropriate error message. + */ +static int k3_rproc_probe(struct udevice *dev) +{ + struct k3_rproc_privdata *priv; + int ret; + + dev_dbg(dev, "%s\n", __func__); + + priv = dev_get_priv(dev); + + ret = k3_rproc_of_to_priv(dev, priv); + if (ret) { + dev_dbg(dev, "%s: Probe failed with error %d\n", __func__, ret); + return ret; + } + + dev_dbg(dev, "Remoteproc successfully probed\n"); + + return 0; +} + +static const struct udevice_id k3_rproc_ids[] = { + { .compatible = "ti,am654-rproc"}, + {} +}; + +U_BOOT_DRIVER(k3_rproc) = { + .name = "k3_rproc", + .of_match = k3_rproc_ids, + .id = UCLASS_REMOTEPROC, + .ops = &k3_rproc_ops, + .probe = k3_rproc_probe, + .priv_auto_alloc_size = sizeof(struct k3_rproc_privdata), +}; From patchwork Tue Aug 21 14:32:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960450 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="u5+k/ptB"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtnF64jYz9s5b for ; Wed, 22 Aug 2018 00:47:29 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 7BF7DC21E1B; Tue, 21 Aug 2018 14:46:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id E4FA3C21EF2; Tue, 21 Aug 2018 14:38:05 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 23453C21EFF; Tue, 21 Aug 2018 14:34:21 +0000 (UTC) Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) by lists.denx.de (Postfix) with ESMTPS id 0263CC21E7E for ; Tue, 21 Aug 2018 14:34:15 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEYEno116157; Tue, 21 Aug 2018 09:34:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1534862054; bh=ETkZkp6anfSmnYY0o+bVqCZ89rJDK9NYmIAMCvbt5zA=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=u5+k/ptBguCZezIkc+0at5wRpFKCoXPwFlNv3dHVncIpxagDKZlV4mEP42bGRnSgX HCYazIuKBskB1MM6F/uX0Xle+Q8fLViiZXSFwf8l1oqHbuIEBsHoW0/0DV8mqSAAgc rFULvmIl2juytSaNaI4wAkLLp7IPfh4f3jvUXcI4= Received: from DFLE100.ent.ti.com (dfle100.ent.ti.com [10.64.6.21]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEYESa019884; Tue, 21 Aug 2018 09:34:14 -0500 Received: from DFLE102.ent.ti.com (10.64.6.23) by DFLE100.ent.ti.com (10.64.6.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:34:14 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE102.ent.ti.com (10.64.6.23) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:34:14 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhi016556; Tue, 21 Aug 2018 09:34:12 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:02:01 +0530 Message-ID: <20180821143203.29142-24-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 23/25] spl: Allow remoteproc drivers to be used within SPL X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" Add an option for building remoteproc drivers within SPL. Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- common/spl/Kconfig | 6 ++++++ drivers/Makefile | 2 +- drivers/remoteproc/Makefile | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 67275eb39d..ba6be4dc40 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -642,6 +642,12 @@ config SPL_RAM_DEVICE be already in memory when SPL takes over, e.g. loaded by the boot ROM. +config SPL_REMOTEPROC + bool "Support REMOTEPROCS" + help + Enable support for REMOTEPROCs in SPL. This permits to load + a remote processor firmware in SPL. + config SPL_RTC_SUPPORT bool "Support RTC drivers" help diff --git a/drivers/Makefile b/drivers/Makefile index c0124765db..23ea609b09 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_$(SPL_TPL_)SPI_FLASH_SUPPORT) += mtd/spi/ obj-$(CONFIG_$(SPL_TPL_)SPI_SUPPORT) += spi/ obj-$(CONFIG_$(SPL_TPL_)TIMER) += timer/ obj-$(CONFIG_$(SPL_)DM_MAILBOX) += mailbox/ +obj-$(CONFIG_$(SPL_)REMOTEPROC) += remoteproc/ ifndef CONFIG_TPL_BUILD ifdef CONFIG_SPL_BUILD @@ -102,7 +103,6 @@ obj-y += input/ # SOC specific infrastructure drivers. obj-y += smem/ obj-y += soc/ -obj-$(CONFIG_REMOTEPROC) += remoteproc/ obj-y += thermal/ obj-y += axi/ diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile index 87ef9e61a7..77eb708523 100644 --- a/drivers/remoteproc/Makefile +++ b/drivers/remoteproc/Makefile @@ -4,7 +4,7 @@ # Texas Instruments Incorporated - http://www.ti.com/ # -obj-$(CONFIG_REMOTEPROC) += rproc-uclass.o +obj-$(CONFIG_$(SPL_)REMOTEPROC) += rproc-uclass.o # Remote proc drivers - Please keep this list alphabetically sorted. obj-$(CONFIG_K3_SYSTEM_CONTROLLER) += k3_system_controller.o From patchwork Tue Aug 21 14:32:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960456 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtqP45KQz9s3x for ; Wed, 22 Aug 2018 00:49:21 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 35D80C21E15; Tue, 21 Aug 2018 14:44:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 07492C21EF1; Tue, 21 Aug 2018 14:36:44 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id A3F98C21EF2; Tue, 21 Aug 2018 14:34:24 +0000 (UTC) Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) by lists.denx.de (Postfix) with ESMTPS id B2434C21E3A for ; Tue, 21 Aug 2018 14:34:18 +0000 (UTC) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEYHYU104854; Tue, 21 Aug 2018 09:34:17 -0500 Received: from DFLE102.ent.ti.com (dfle102.ent.ti.com [10.64.6.23]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEYHvY012259; Tue, 21 Aug 2018 09:34:17 -0500 Received: from DFLE115.ent.ti.com (10.64.6.36) by DFLE102.ent.ti.com (10.64.6.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:34:16 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE115.ent.ti.com (10.64.6.36) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:34:16 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhj016556; Tue, 21 Aug 2018 09:34:14 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:02:02 +0530 Message-ID: <20180821143203.29142-25-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 24/25] mmc: k3_arasan: Add sdhci driver support for K3 family SoCs X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" AM654 has an arasan sdhci controller and a mmc phy attached to it. Add basic support for K3 specific arasan sdhci controller. Cc: Jaehoon Chung Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- drivers/mmc/Kconfig | 9 +++ drivers/mmc/Makefile | 1 + drivers/mmc/k3_arsan_sdhci.c | 109 +++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 drivers/mmc/k3_arsan_sdhci.c diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 377b1c4b3b..27dfccb9b2 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -402,6 +402,15 @@ config MMC_SDHCI_CADENCE If unsure, say N. +config MMC_SDHCI_K3_ARASAN + bool "Arasan SDHCI controller for TI's K3 based SoCs" + depends on ARCH_K3 + depends on MMC_SDHCI + depends on DM_MMC && OF_CONTROL && BLK + help + Support for Arasan SDHCI host controller on Texas Instruments' + K3 family based SoC platforms + config MMC_SDHCI_KONA bool "SDHCI support on Broadcom KONA platform" depends on MMC_SDHCI diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index f6191862d6..23c5b0daef 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -47,6 +47,7 @@ obj-$(CONFIG_MMC_SDHCI_ATMEL) += atmel_sdhci.o obj-$(CONFIG_MMC_SDHCI_BCM2835) += bcm2835_sdhci.o obj-$(CONFIG_MMC_SDHCI_BCMSTB) += bcmstb_sdhci.o obj-$(CONFIG_MMC_SDHCI_CADENCE) += sdhci-cadence.o +obj-$(CONFIG_MMC_SDHCI_K3_ARASAN) += k3_arsan_sdhci.o obj-$(CONFIG_MMC_SDHCI_KONA) += kona_sdhci.o obj-$(CONFIG_MMC_SDHCI_MSM) += msm_sdhci.o obj-$(CONFIG_MMC_SDHCI_MV) += mv_sdhci.o diff --git a/drivers/mmc/k3_arsan_sdhci.c b/drivers/mmc/k3_arsan_sdhci.c new file mode 100644 index 0000000000..1da25dc55d --- /dev/null +++ b/drivers/mmc/k3_arsan_sdhci.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * + * Texas Instruments' K3 SD Host Controller Interface + */ + +#include +#include +#include +#include +#include +#include + +#define K3_ARASAN_SDHCI_MIN_FREQ 0 + +struct k3_arasan_sdhci_plat { + struct mmc_config cfg; + struct mmc mmc; + unsigned int f_max; +}; + +static int k3_arasan_sdhci_probe(struct udevice *dev) +{ + struct k3_arasan_sdhci_plat *plat = dev_get_platdata(dev); + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct sdhci_host *host = dev_get_priv(dev); + struct power_domain sdhci_pwrdmn; + struct clk clk; + unsigned long clock; + int ret; + + ret = power_domain_get_by_index(dev, &sdhci_pwrdmn, 0); + if (ret) { + dev_err(dev, "failed to get power domain\n"); + return ret; + } + + ret = power_domain_on(&sdhci_pwrdmn); + if (ret) { + dev_err(dev, "Power domain on failed\n"); + return ret; + } + + ret = clk_get_by_index(dev, 0, &clk); + if (ret) { + dev_err(dev, "failed to get clock\n"); + return ret; + } + + clock = clk_get_rate(&clk); + if (IS_ERR_VALUE(clock)) { + dev_err(dev, "failed to get rate\n"); + return clock; + } + + host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | + SDHCI_QUIRK_BROKEN_R1B; + + host->max_clk = clock; + + ret = sdhci_setup_cfg(&plat->cfg, host, plat->f_max, + K3_ARASAN_SDHCI_MIN_FREQ); + host->mmc = &plat->mmc; + if (ret) + return ret; + host->mmc->priv = host; + host->mmc->dev = dev; + upriv->mmc = host->mmc; + + return sdhci_probe(dev); +} + +static int k3_arasan_sdhci_ofdata_to_platdata(struct udevice *dev) +{ + struct k3_arasan_sdhci_plat *plat = dev_get_platdata(dev); + struct sdhci_host *host = dev_get_priv(dev); + + host->name = dev->name; + host->ioaddr = (void *)dev_read_addr(dev); + host->bus_width = dev_read_u32_default(dev, "bus-width", 4); + plat->f_max = dev_read_u32_default(dev, "max-frequency", 0); + + return 0; +} + +static int k3_arasan_sdhci_bind(struct udevice *dev) +{ + struct k3_arasan_sdhci_plat *plat = dev_get_platdata(dev); + + return sdhci_bind(dev, &plat->mmc, &plat->cfg); +} + +static const struct udevice_id k3_arasan_sdhci_ids[] = { + { .compatible = "arasan,sdhci-5.1" }, + { } +}; + +U_BOOT_DRIVER(k3_arasan_sdhci_drv) = { + .name = "k3_arasan_sdhci", + .id = UCLASS_MMC, + .of_match = k3_arasan_sdhci_ids, + .ofdata_to_platdata = k3_arasan_sdhci_ofdata_to_platdata, + .ops = &sdhci_ops, + .bind = k3_arasan_sdhci_bind, + .probe = k3_arasan_sdhci_probe, + .priv_auto_alloc_size = sizeof(struct sdhci_host), + .platdata_auto_alloc_size = sizeof(struct k3_arasan_sdhci_plat), +}; From patchwork Tue Aug 21 14:32:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 960470 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41vtxx3sXsz9s3x for ; Wed, 22 Aug 2018 00:55:01 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 4AEEDC21E57; Tue, 21 Aug 2018 14:45:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 6FD74C21E5B; Tue, 21 Aug 2018 14:37:59 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 8A767C21E49; Tue, 21 Aug 2018 14:34:25 +0000 (UTC) Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) by lists.denx.de (Postfix) with ESMTPS id 5D3A6C21E45 for ; Tue, 21 Aug 2018 14:34:21 +0000 (UTC) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id w7LEYJJe104871; Tue, 21 Aug 2018 09:34:19 -0500 Received: from DLEE105.ent.ti.com (dlee105.ent.ti.com [157.170.170.35]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEYJuF012312; Tue, 21 Aug 2018 09:34:19 -0500 Received: from DLEE104.ent.ti.com (157.170.170.34) by DLEE105.ent.ti.com (157.170.170.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Tue, 21 Aug 2018 09:34:18 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE104.ent.ti.com (157.170.170.34) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Tue, 21 Aug 2018 09:34:18 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w7LEXKhk016556; Tue, 21 Aug 2018 09:34:17 -0500 From: Lokesh Vutla To: Tom Rini , Date: Tue, 21 Aug 2018 20:02:03 +0530 Message-ID: <20180821143203.29142-26-lokeshvutla@ti.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180821143203.29142-1-lokeshvutla@ti.com> References: <20180821143203.29142-1-lokeshvutla@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tero Kristo Subject: [U-Boot] [PATCH 25/25] gpio: do not include for ARCH_K3 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" As no gpio.h is defined in arch/arm/mach-k3/include/, to avoid compilation failure, do not include asm/arch/gpio.h. Signed-off-by: Lokesh Vutla Reviewed-by: Tom Rini --- arch/arm/include/asm/gpio.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h index 1c5e87340c..3039e66bf9 100644 --- a/arch/arm/include/asm/gpio.h +++ b/arch/arm/include/asm/gpio.h @@ -1,4 +1,5 @@ -#if !defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARCH_STI) +#if !defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARCH_STI) && \ + !defined(CONFIG_ARCH_K3) #include #endif #include