From patchwork Mon Jul 9 15:50:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Georgi Djakov X-Patchwork-Id: 141452 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2822229ljj; Mon, 9 Jul 2018 08:51:22 -0700 (PDT) X-Google-Smtp-Source: AAOMgpc8EzOMLOxqS3jZ5m761azvoHwZR2SZR0eJsVKtYvWUbjB5HpFd9uNkiKQuMCcyKrPbMOc7 X-Received: by 2002:a17:902:768a:: with SMTP id m10-v6mr21153016pll.293.1531151482313; Mon, 09 Jul 2018 08:51:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531151482; cv=none; d=google.com; s=arc-20160816; b=hO+kDggdgEvYeXYi6vCNitvAK9FPKaJ5CqdPCQqaTYJ0p2bG6Zp21qgf/a7FwOhjzT wknvx7/xI6odb9lqSE/i/Nant3l+DwANu3tiz0Zn5duFZqwE3OucZHWot8lUX07jL5Lv swhqVBfQEt4X12f3F8DSJ9DL3ZoQTZM1WzkDdLY2cDVPN4e7hvL/nlWrM08wRJIGkhR8 f2hNAYXCX6k6kaUC+I8h+Mi83RoSHT4BVj1Mg3jDZR0j6+egVhaRGyENN0jt9hi0NAV4 KCAjLE5PDgFrln5NUHHwxqrfi25k3lzT9C5aMypG+iu6WSE0fe9dFNSmCuOkIEqvUg0p ATkA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=1WP8TPVFDoHW/bxl+hSFy6QWs7P1JQ8Gq8qayJGFtT8=; b=uTmgLJ7RcIMpBWdKt5erA4v79TrcSdBCJPZT2edB8eH6cBJPAEkU3KbPzC2ri9KFSJ PuTU8N++I3DemstlkvAtIiMDn7EsF2yLRqWSYvw+HUgOV5KKk+8ncdRwJYQGFuMsHBkv Rg7BdVKIPQGKJew2aqqJZ3fbdTIQLjyi/eitvl5AMHMiY2RiZ5wJbvJ3HR/D0nsE5DjF 5SoVadqJLiXRkp63XrPLiZw2F7INUkji702DfciAcEHuqc0iXDsAmKQSJKt70kIb+jqf eyqrjzpoVEIwN6qBkENN38OZYRU5Vo/QYooEZvoF6cbYrPQ/9jVcbU0+TFrRI5C4EGJV L0ZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FvlccFhd; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i18-v6si13977932pgn.433.2018.07.09.08.51.22; Mon, 09 Jul 2018 08:51:22 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FvlccFhd; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933836AbeGIPvQ (ORCPT + 30 others); Mon, 9 Jul 2018 11:51:16 -0400 Received: from mail-wr1-f68.google.com ([209.85.221.68]:42580 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933774AbeGIPvK (ORCPT ); Mon, 9 Jul 2018 11:51:10 -0400 Received: by mail-wr1-f68.google.com with SMTP id p1-v6so11508555wrs.9 for ; Mon, 09 Jul 2018 08:51:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1WP8TPVFDoHW/bxl+hSFy6QWs7P1JQ8Gq8qayJGFtT8=; b=FvlccFhdZYnjdS5pNDD2ravTpv+ahIgTj4xNin4jTcBmlp7XjF2Pja+iWsbfuUMrZM J/geUpUWfh9G8aJk10U/O3LWYAlWsmTslLRiS0XaeicSJySROCQvrH6+0MU56oFpkcDM 5XRXBhtfjkk6oCNBYZX8sqJBmLEkN8T4Y2RtE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=1WP8TPVFDoHW/bxl+hSFy6QWs7P1JQ8Gq8qayJGFtT8=; b=o886TGqsD3MUmT/eMyacgqZEvI0x7pto+S/URyxsKg2jSSp999oZeybzZOO1t20bnz ZKwTr+D97cuSp4Kf0hxBIM9hLwWWDnm2WGVHaWph2aHS5+8AAKR8C2swg6xEaKjr0DML HI9Xa8oo0Nq33S8ORJkC1ReqiUoiw2Et5JSx2gi/veSkyyG3tQP4P4HK87MzyObpKB/2 2vk3dpUCgRYiPmn2vgNLSHVlQggAaERXLucZuAJi4EkBGmztiApHhn0DYLJxY8Isf3IO nDJymfoBg9JJPYRtiS6pwiv8JrAZs+VLJpfQddePukpt3BhL3KEi7KX/Gmp4HAne8VhH FxWQ== X-Gm-Message-State: APt69E2CJU6nf5gyGeZWnn7CCOG11g+IuKxw1jwEB54Pi2altzuxj//c 3hBkhIQNW3amOLjGeFEPnHZC8A== X-Received: by 2002:adf:af27:: with SMTP id z36-v6mr14270235wrc.59.1531151469078; Mon, 09 Jul 2018 08:51:09 -0700 (PDT) Received: from localhost.localdomain ([212.45.67.2]) by smtp.googlemail.com with ESMTPSA id o21-v6sm16229202wmg.28.2018.07.09.08.51.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Jul 2018 08:51:08 -0700 (PDT) From: Georgi Djakov To: linux-pm@vger.kernel.org, gregkh@linuxfoundation.org Cc: rjw@rjwysocki.net, robh+dt@kernel.org, mturquette@baylibre.com, khilman@baylibre.com, abailon@baylibre.com, vincent.guittot@linaro.org, skannan@codeaurora.org, bjorn.andersson@linaro.org, amit.kucheria@linaro.org, seansw@qti.qualcomm.com, daidavid1@codeaurora.org, evgreen@chromium.org, mka@chromium.org, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org, georgi.djakov@linaro.org Subject: [PATCH v6 1/8] interconnect: Add generic on-chip interconnect API Date: Mon, 9 Jul 2018 18:50:57 +0300 Message-Id: <20180709155104.25528-2-georgi.djakov@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180709155104.25528-1-georgi.djakov@linaro.org> References: <20180709155104.25528-1-georgi.djakov@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch introduces a new API to get requirements and configure the interconnect buses across the entire chipset to fit with the current demand. The API is using a consumer/provider-based model, where the providers are the interconnect buses and the consumers could be various drivers. The consumers request interconnect resources (path) between endpoints and set the desired constraints on this data flow path. The providers receive requests from consumers and aggregate these requests for all master-slave pairs on that path. Then the providers configure each participating in the topology node according to the requested data flow path, physical links and constraints. The topology could be complicated and multi-tiered and is SoC specific. Signed-off-by: Georgi Djakov --- Documentation/interconnect/interconnect.rst | 96 ++++ drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/interconnect/Kconfig | 10 + drivers/interconnect/Makefile | 2 + drivers/interconnect/core.c | 597 ++++++++++++++++++++ include/linux/interconnect-provider.h | 130 +++++ include/linux/interconnect.h | 42 ++ 8 files changed, 880 insertions(+) create mode 100644 Documentation/interconnect/interconnect.rst create mode 100644 drivers/interconnect/Kconfig create mode 100644 drivers/interconnect/Makefile create mode 100644 drivers/interconnect/core.c create mode 100644 include/linux/interconnect-provider.h create mode 100644 include/linux/interconnect.h diff --git a/Documentation/interconnect/interconnect.rst b/Documentation/interconnect/interconnect.rst new file mode 100644 index 000000000000..a1ebd83ad0a1 --- /dev/null +++ b/Documentation/interconnect/interconnect.rst @@ -0,0 +1,96 @@ +.. SPDX-License-Identifier: GPL-2.0 + +===================================== +GENERIC SYSTEM INTERCONNECT SUBSYSTEM +===================================== + +Introduction +------------ + +This framework is designed to provide a standard kernel interface to control +the settings of the interconnects on a SoC. These settings can be throughput, +latency and priority between multiple interconnected devices or functional +blocks. This can be controlled dynamically in order to save power or provide +maximum performance. + +The interconnect bus is a hardware with configurable parameters, which can be +set on a data path according to the requests received from various drivers. +An example of interconnect buses are the interconnects between various +components or functional blocks in chipsets. There can be multiple interconnects +on a SoC that can be multi-tiered. + +Below is a simplified diagram of a real-world SoC interconnect bus topology. + +:: + + +----------------+ +----------------+ + | HW Accelerator |--->| M NoC |<---------------+ + +----------------+ +----------------+ | + | | +------------+ + +-----+ +-------------+ V +------+ | | + | DDR | | +--------+ | PCIe | | | + +-----+ | | Slaves | +------+ | | + ^ ^ | +--------+ | | C NoC | + | | V V | | + +------------------+ +------------------------+ | | +-----+ + | |-->| |-->| |-->| CPU | + | |-->| |<--| | +-----+ + | Mem NoC | | S NoC | +------------+ + | |<--| |---------+ | + | |<--| |<------+ | | +--------+ + +------------------+ +------------------------+ | | +-->| Slaves | + ^ ^ ^ ^ ^ | | +--------+ + | | | | | | V + +------+ | +-----+ +-----+ +---------+ +----------------+ +--------+ + | CPUs | | | GPU | | DSP | | Masters |-->| P NoC |-->| Slaves | + +------+ | +-----+ +-----+ +---------+ +----------------+ +--------+ + | + +-------+ + | Modem | + +-------+ + +Terminology +----------- + +Interconnect provider is the software definition of the interconnect hardware. +The interconnect providers on the above diagram are M NoC, S NoC, C NoC, P NoC +and Mem NoC. + +Interconnect node is the software definition of the interconnect hardware +port. Each interconnect provider consists of multiple interconnect nodes, +which are connected to other SoC components including other interconnect +providers. The point on the diagram where the CPUs connects to the memory is +called an interconnect node, which belongs to the Mem NoC interconnect provider. + +Interconnect endpoints are the first or the last element of the path. Every +endpoint is a node, but not every node is an endpoint. + +Interconnect path is everything between two endpoints including all the nodes +that have to be traversed to reach from a source to destination node. It may +include multiple master-slave pairs across several interconnect providers. + +Interconnect consumers are the entities which make use of the data paths exposed +by the providers. The consumers send requests to providers requesting various +throughput, latency and priority. Usually the consumers are device drivers, that +send request based on their needs. An example for a consumer is a video decoder +that supports various formats and image sizes. + +Interconnect providers +---------------------- + +Interconnect provider is an entity that implements methods to initialize and +configure a interconnect bus hardware. The interconnect provider drivers should +be registered with the interconnect provider core. + +The interconnect framework provider API functions are documented in +.. kernel-doc:: include/linux/interconnect-provider.h + +Interconnect consumers +---------------------- + +Interconnect consumers are the clients which use the interconnect APIs to +get paths between endpoints and set their bandwidth/latency/QoS requirements +for these interconnect paths. + +The interconnect framework consumer API functions are documented in +.. kernel-doc:: include/linux/interconnect.h diff --git a/drivers/Kconfig b/drivers/Kconfig index 95b9ccc08165..3ed6ede9d021 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -217,4 +217,6 @@ source "drivers/siox/Kconfig" source "drivers/slimbus/Kconfig" +source "drivers/interconnect/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 24cd47014657..0cca95740d9b 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -185,3 +185,4 @@ obj-$(CONFIG_TEE) += tee/ obj-$(CONFIG_MULTIPLEXER) += mux/ obj-$(CONFIG_UNISYS_VISORBUS) += visorbus/ obj-$(CONFIG_SIOX) += siox/ +obj-$(CONFIG_INTERCONNECT) += interconnect/ diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig new file mode 100644 index 000000000000..a261c7d41deb --- /dev/null +++ b/drivers/interconnect/Kconfig @@ -0,0 +1,10 @@ +menuconfig INTERCONNECT + tristate "On-Chip Interconnect management support" + help + Support for management of the on-chip interconnects. + + This framework is designed to provide a generic interface for + managing the interconnects in a SoC. + + If unsure, say no. + diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile new file mode 100644 index 000000000000..97fca2e09d24 --- /dev/null +++ b/drivers/interconnect/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_INTERCONNECT) += core.o diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c new file mode 100644 index 000000000000..63707c3c3d48 --- /dev/null +++ b/drivers/interconnect/core.c @@ -0,0 +1,597 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Interconnect framework core driver + * + * Copyright (c) 2018, Linaro Ltd. + * Author: Georgi Djakov + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_IDR(icc_idr); +static LIST_HEAD(icc_provider_list); +static DEFINE_MUTEX(icc_lock); + +/** + * struct icc_req - constraints that are attached to each node + * + * @req_node: entry in list of requests for the particular @node + * @node: the interconnect node to which this constraint applies + * @dev: reference to the device that sets the constraints + * @avg_bw: an integer describing the average bandwidth in kbps + * @peak_bw: an integer describing the peak bandwidth in kbps + */ +struct icc_req { + struct hlist_node req_node; + struct icc_node *node; + struct device *dev; + u32 avg_bw; + u32 peak_bw; +}; + +/** + * struct icc_path - interconnect path structure + * @num_nodes: number of hops (nodes) + * @reqs: array of the requests applicable to this path of nodes + */ +struct icc_path { + size_t num_nodes; + struct icc_req reqs[]; +}; + +static struct icc_node *node_find(const int id) +{ + return idr_find(&icc_idr, id); +} + +static struct icc_path *path_init(struct device *dev, struct icc_node *dst, + ssize_t num_nodes) +{ + struct icc_node *node = dst; + struct icc_path *path; + size_t i; + + path = kzalloc(struct_size(path, reqs, num_nodes), GFP_KERNEL); + if (!path) + return ERR_PTR(-ENOMEM); + + path->num_nodes = num_nodes; + + for (i = 0; i < num_nodes; i++) { + hlist_add_head(&path->reqs[i].req_node, &node->req_list); + + path->reqs[i].node = node; + path->reqs[i].dev = dev; + /* reference to previous node was saved during path traversal */ + node = node->reverse; + } + + return path; +} + +static struct icc_path *path_find(struct device *dev, struct icc_node *src, + struct icc_node *dst) +{ + struct icc_node *n, *node = NULL; + struct icc_provider *provider; + struct list_head traverse_list; + struct list_head edge_list; + struct list_head visited_list; + size_t i, depth = 1; + bool found = false; + int ret = -EPROBE_DEFER; + + INIT_LIST_HEAD(&traverse_list); + INIT_LIST_HEAD(&edge_list); + INIT_LIST_HEAD(&visited_list); + + list_add_tail(&src->search_list, &traverse_list); + src->reverse = NULL; + + do { + list_for_each_entry_safe(node, n, &traverse_list, search_list) { + if (node == dst) { + found = true; + list_add(&node->search_list, &visited_list); + break; + } + for (i = 0; i < node->num_links; i++) { + struct icc_node *tmp = node->links[i]; + + if (!tmp) { + ret = -ENOENT; + goto out; + } + + if (tmp->is_traversed) + continue; + + tmp->is_traversed = true; + tmp->reverse = node; + list_add(&tmp->search_list, &edge_list); + } + } + if (found) + break; + + list_splice_init(&traverse_list, &visited_list); + list_splice_init(&edge_list, &traverse_list); + + /* count the hops including the source */ + depth++; + + } while (!list_empty(&traverse_list)); + +out: + /* reset the traversed state */ + list_for_each_entry(provider, &icc_provider_list, provider_list) + list_for_each_entry(n, &provider->nodes, node_list) + n->is_traversed = false; + + if (found) { + struct icc_path *path = path_init(dev, dst, depth); + + if (IS_ERR(path)) + return path; + + for (i = 0; i < path->num_nodes; i++) { + node = path->reqs[i].node; + node->provider->users++; + } + return path; + } + + return ERR_PTR(ret); +} + +/* + * We want the path to honor all bandwidth requests, so the average + * bandwidth requirements from each consumer are aggregated at each node + * and provider level. By default the average bandwidth is the sum of all + * averages and the peak will be the highest of all peak bandwidth requests. + */ + +static int aggregate_requests(struct icc_node *node) +{ + struct icc_provider *p = node->provider; + struct icc_req *r; + + node->avg_bw = 0; + node->peak_bw = 0; + + hlist_for_each_entry(r, &node->req_list, req_node) + p->aggregate(node, r->avg_bw, r->peak_bw, + &node->avg_bw, &node->peak_bw); + + return 0; +} + +static void aggregate_provider(struct icc_provider *p) +{ + struct icc_node *n; + + p->avg_bw = 0; + p->peak_bw = 0; + + list_for_each_entry(n, &p->nodes, node_list) + p->aggregate(n, n->avg_bw, n->peak_bw, + &p->avg_bw, &p->peak_bw); +} + +static int apply_constraints(struct icc_path *path) +{ + struct icc_node *next, *prev = NULL; + int ret; + int i; + + for (i = 0; i < path->num_nodes; i++, prev = next) { + struct icc_provider *p; + + next = path->reqs[i].node; + /* + * Both endpoints should be valid master-slave pairs of the + * same interconnect provider that will be configured. + */ + if (!prev || next->provider != prev->provider) + continue; + + p = next->provider; + + aggregate_provider(p); + + /* set the constraints */ + ret = p->set(prev, next, p->avg_bw, p->peak_bw); + if (ret) + goto out; + } +out: + return ret; +} + +/** + * icc_set() - set constraints on an interconnect path between two endpoints + * @path: reference to the path returned by icc_get() + * @avg_bw: average bandwidth in kbps + * @peak_bw: peak bandwidth in kbps + * + * This function is used by an interconnect consumer to express its own needs + * in terms of bandwidth for a previously requested path between two endpoints. + * The requests are aggregated and each node is updated accordingly. The entire + * path is locked by a mutex to ensure that the set() is completed. + * The @path can be NULL when the "interconnects" DT properties is missing, + * which will mean that no constraints will be set. + * + * Returns 0 on success, or an appropriate error code otherwise. + */ +int icc_set(struct icc_path *path, u32 avg_bw, u32 peak_bw) +{ + struct icc_node *node; + struct icc_provider *p; + size_t i; + int ret; + + if (!path) + return 0; + + mutex_lock(&icc_lock); + + for (i = 0; i < path->num_nodes; i++) { + node = path->reqs[i].node; + p = node->provider; + + /* update the consumer request for this path */ + path->reqs[i].avg_bw = avg_bw; + path->reqs[i].peak_bw = peak_bw; + + /* aggregate requests for this node */ + aggregate_requests(node); + } + + ret = apply_constraints(path); + if (ret) + pr_err("interconnect: error applying constraints (%d)", ret); + + mutex_unlock(&icc_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(icc_set); + +/** + * icc_get() - return a handle for path between two endpoints + * @dev: the device requesting the path + * @src_id: source device port id + * @dst_id: destination device port id + * + * This function will search for a path between two endpoints and return an + * icc_path handle on success. Use icc_put() to release + * constraints when the they are not needed anymore. + * + * Return: icc_path pointer on success, or ERR_PTR() on error + */ +struct icc_path *icc_get(struct device *dev, const int src_id, const int dst_id) +{ + struct icc_node *src, *dst; + struct icc_path *path = ERR_PTR(-EPROBE_DEFER); + + mutex_lock(&icc_lock); + + src = node_find(src_id); + if (!src) + goto out; + + dst = node_find(dst_id); + if (!dst) + goto out; + + path = path_find(dev, src, dst); + if (IS_ERR(path)) + dev_err(dev, "%s: invalid path=%ld\n", __func__, PTR_ERR(path)); + +out: + mutex_unlock(&icc_lock); + return path; +} +EXPORT_SYMBOL_GPL(icc_get); + +/** + * icc_put() - release the reference to the icc_path + * @path: interconnect path + * + * Use this function to release the constraints on a path when the path is + * no longer needed. The constraints will be re-aggregated. + */ +void icc_put(struct icc_path *path) +{ + struct icc_node *node; + size_t i; + int ret; + + if (!path || WARN_ON(IS_ERR(path))) + return; + + ret = icc_set(path, 0, 0); + if (ret) + pr_err("%s: error (%d)\n", __func__, ret); + + mutex_lock(&icc_lock); + for (i = 0; i < path->num_nodes; i++) { + node = path->reqs[i].node; + hlist_del(&path->reqs[i].req_node); + + node->provider->users--; + } + mutex_unlock(&icc_lock); + + kfree(path); +} +EXPORT_SYMBOL_GPL(icc_put); + +static struct icc_node *icc_node_create_nolock(int id) +{ + struct icc_node *node; + + /* check if node already exists */ + node = node_find(id); + if (node) + goto out; + + node = kzalloc(sizeof(*node), GFP_KERNEL); + if (!node) { + node = ERR_PTR(-ENOMEM); + goto out; + } + + id = idr_alloc(&icc_idr, node, id, id + 1, GFP_KERNEL); + if (WARN(id < 0, "couldn't get idr")) { + kfree(node); + node = ERR_PTR(id); + goto out; + } + + node->id = id; + +out: + return node; +} + +/** + * icc_node_create() - create a node + * @id: node id + * + * Return: icc_node pointer on success, or ERR_PTR() on error + */ +struct icc_node *icc_node_create(int id) +{ + struct icc_node *node; + + mutex_lock(&icc_lock); + + node = icc_node_create_nolock(id); + + mutex_unlock(&icc_lock); + + return node; +} +EXPORT_SYMBOL_GPL(icc_node_create); + +/** + * icc_node_destroy() - destroy a node + * @id: node id + * + */ +void icc_node_destroy(int id) +{ + struct icc_node *node; + + node = node_find(id); + if (node) { + mutex_lock(&icc_lock); + idr_remove(&icc_idr, node->id); + WARN_ON(!hlist_empty(&node->req_list)); + mutex_unlock(&icc_lock); + } + + kfree(node); +} +EXPORT_SYMBOL_GPL(icc_node_destroy); + +/** + * icc_link_create() - create a link between two nodes + * @src_id: source node id + * @dst_id: destination node id + * + * Create a link between two nodes. The nodes might belong to different + * interconnect providers and the @dst_id node might not exist (if the + * provider driver has not probed yet). So just create the @dst_id node + * and when the actual provider driver is probed, the rest of the node + * data is filled. + * + * Return: 0 on success, or an error code otherwise + */ +int icc_link_create(struct icc_node *node, const int dst_id) +{ + struct icc_node *dst; + struct icc_node **new; + int ret = 0; + + if (!node->provider) + return -EINVAL; + + mutex_lock(&icc_lock); + + dst = node_find(dst_id); + if (!dst) { + dst = icc_node_create_nolock(dst_id); + + if (IS_ERR(dst)) { + ret = PTR_ERR(dst); + goto out; + } + } + + new = krealloc(node->links, + (node->num_links + 1) * sizeof(*node->links), + GFP_KERNEL); + if (!new) { + ret = -ENOMEM; + goto out; + } + + node->links = new; + node->links[node->num_links++] = dst; + +out: + mutex_unlock(&icc_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(icc_link_create); + +/** + * icc_link_destroy() - destroy a link between two nodes + * @src: pointer to source node + * @dst: pointer to destination node + * + * Return: 0 on success, or an error code otherwise + */ +int icc_link_destroy(struct icc_node *src, struct icc_node *dst) +{ + struct icc_node **new; + struct icc_node *last; + int ret = 0; + size_t slot; + + if (IS_ERR_OR_NULL(src)) + return -EINVAL; + + if (IS_ERR_OR_NULL(dst)) + return -EINVAL; + + mutex_lock(&icc_lock); + + for (slot = 0; slot < src->num_links; slot++) + if (src->links[slot] == dst) + break; + + last = src->links[src->num_links]; + + new = krealloc(src->links, + (src->num_links - 1) * sizeof(*src->links), + GFP_KERNEL); + if (!new) { + ret = -ENOMEM; + goto out; + } + + src->links = new; + + if (slot < src->num_links - 1) + /* move the last element to the slot that was freed */ + src->links[slot] = last; + + src->num_links--; + +out: + mutex_unlock(&icc_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(icc_link_destroy); + +/** + * icc_node_add() - add interconnect node to interconnect provider + * @node: pointer to the interconnect node + * @provider: pointer to the interconnect provider + * + */ +void icc_node_add(struct icc_node *node, struct icc_provider *provider) +{ + mutex_lock(&icc_lock); + + node->provider = provider; + list_add(&node->node_list, &provider->nodes); + + mutex_unlock(&icc_lock); +} +EXPORT_SYMBOL_GPL(icc_node_add); + +/** + * icc_node_del() - delete interconnect node from interconnect provider + * @node: pointer to the interconnect node + * + */ +void icc_node_del(struct icc_node *node) +{ + mutex_lock(&icc_lock); + + list_del(&node->node_list); + + mutex_unlock(&icc_lock); +} +EXPORT_SYMBOL_GPL(icc_node_del); + +/** + * icc_provider_add() - add a new interconnect provider + * @icc_provider: the interconnect provider that will be added into topology + * + * Return: 0 on success, or an error code otherwise + */ +int icc_provider_add(struct icc_provider *provider) +{ + if (WARN_ON(!provider->set)) + return -EINVAL; + + mutex_lock(&icc_lock); + + INIT_LIST_HEAD(&provider->nodes); + list_add(&provider->provider_list, &icc_provider_list); + + mutex_unlock(&icc_lock); + + dev_dbg(provider->dev, "interconnect provider added to topology\n"); + + return 0; +} +EXPORT_SYMBOL_GPL(icc_provider_add); + +/** + * icc_provider_del() - delete previously added interconnect provider + * @icc_provider: the interconnect provider that will be removed from topology + * + * Return: 0 on success, or an error code otherwise + */ +int icc_provider_del(struct icc_provider *provider) +{ + mutex_lock(&icc_lock); + if (provider->users) { + pr_warn("interconnect provider still has %d users\n", + provider->users); + mutex_unlock(&icc_lock); + return -EBUSY; + } + + if (!list_empty(&provider->nodes)) { + pr_warn("interconnect provider still has nodes\n"); + mutex_unlock(&icc_lock); + return -EBUSY; + } + + list_del(&provider->provider_list); + mutex_unlock(&icc_lock); + + return 0; +} +EXPORT_SYMBOL_GPL(icc_provider_del); + +MODULE_AUTHOR("Georgi Djakov + */ + +#ifndef _LINUX_INTERCONNECT_PROVIDER_H +#define _LINUX_INTERCONNECT_PROVIDER_H + +#include + +#define icc_units_to_bps(bw) ((bw) * 1000ULL) + +struct icc_node; + +/** + * struct icc_provider - interconnect provider (controller) entity that might + * provide multiple interconnect controls + * + * @provider_list: list of the registered interconnect providers + * @nodes: internal list of the interconnect provider nodes + * @set: pointer to device specific set operation function + * @aggregate: pointer to device specific aggregate operation function + * @dev: the device this interconnect provider belongs to + * @users: count of active users + * @avg_bw: aggregated value of average bandwidth requests from all nodes + * @peak_bw: aggregated value of peak bandwidth requests from all nodes + * @data: pointer to private data + */ +struct icc_provider { + struct list_head provider_list; + struct list_head nodes; + int (*set)(struct icc_node *src, struct icc_node *dst, + u32 avg_bw, u32 peak_bw); + int (*aggregate)(struct icc_node *node, u32 avg_bw, u32 peak_bw, + u32 *agg_avg, u32 *agg_peak); + struct device *dev; + int users; + u32 avg_bw; + u32 peak_bw; + void *data; +}; + +/** + * struct icc_node - entity that is part of the interconnect topology + * + * @id: platform specific node id + * @name: node name used in debugfs + * @links: a list of targets pointing to where we can go next when traversing + * @num_links: number of links to other interconnect nodes + * @provider: points to the interconnect provider of this node + * @node_list: the list entry in the parent provider's "nodes" list + * @search_list: list used when walking the nodes graph + * @reverse: pointer to previous node when walking the nodes graph + * @is_traversed: flag that is used when walking the nodes graph + * @req_list: a list of QoS constraint requests associated with this node + * @avg_bw: aggregated value of average bandwidth requests from all consumers + * @peak_bw: aggregated value of peak bandwidth requests from all consumers + * @data: pointer to private data + */ +struct icc_node { + int id; + const char *name; + struct icc_node **links; + size_t num_links; + + struct icc_provider *provider; + struct list_head node_list; + struct list_head search_list; + struct icc_node *reverse; + bool is_traversed; + struct hlist_head req_list; + u32 avg_bw; + u32 peak_bw; + void *data; +}; + +#if IS_ENABLED(CONFIG_INTERCONNECT) + +struct icc_node *icc_node_create(int id); +void icc_node_destroy(int id); +int icc_link_create(struct icc_node *node, const int dst_id); +int icc_link_destroy(struct icc_node *src, struct icc_node *dst); +void icc_node_add(struct icc_node *node, struct icc_provider *provider); +void icc_node_del(struct icc_node *node); +int icc_provider_add(struct icc_provider *provider); +int icc_provider_del(struct icc_provider *provider); + +#else + +static inline struct icc_node *icc_node_create(int id) +{ + return ERR_PTR(-ENOTSUPP); +} + +void icc_node_destroy(int id) +{ +} + +static inline int icc_link_create(struct icc_node *node, const int dst_id) +{ + return -ENOTSUPP; +} + +int icc_link_destroy(struct icc_node *src, struct icc_node *dst) +{ + return -ENOTSUPP; +} + +void icc_node_add(struct icc_node *node, struct icc_provider *provider) +{ +} + +void icc_node_del(struct icc_node *node) +{ +} + +static inline int icc_provider_add(struct icc_provider *provider) +{ + return -ENOTSUPP; +} + +static inline int icc_provider_del(struct icc_provider *provider) +{ + return -ENOTSUPP; +} + +#endif /* CONFIG_INTERCONNECT */ + +#endif /* _LINUX_INTERCONNECT_PROVIDER_H */ diff --git a/include/linux/interconnect.h b/include/linux/interconnect.h new file mode 100644 index 000000000000..593215371fd6 --- /dev/null +++ b/include/linux/interconnect.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, Linaro Ltd. + * Author: Georgi Djakov + */ + +#ifndef _LINUX_INTERCONNECT_H +#define _LINUX_INTERCONNECT_H + +#include +#include + +struct icc_path; +struct device; + +#if IS_ENABLED(CONFIG_INTERCONNECT) + +struct icc_path *icc_get(struct device *dev, const int src_id, + const int dst_id); +void icc_put(struct icc_path *path); +int icc_set(struct icc_path *path, u32 avg_bw, u32 peak_bw); + +#else + +static inline struct icc_path *icc_get(struct device *dev, const int src_id, + const int dst_id) +{ + return NULL; +} + +static inline void icc_put(struct icc_path *path) +{ +} + +static inline int icc_set(struct icc_path *path, u32 avg_bw, u32 peak_bw) +{ + return 0; +} + +#endif /* CONFIG_INTERCONNECT */ + +#endif /* _LINUX_INTERCONNECT_H */ From patchwork Mon Jul 9 15:50:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Georgi Djakov X-Patchwork-Id: 141458 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2826281ljj; Mon, 9 Jul 2018 08:55:43 -0700 (PDT) X-Google-Smtp-Source: AAOMgpf+M4dU60a3/1DMojsN3wA8jYUtWHfpDVwsRuWLDoGjPNl9wBzSwTCJMvG9/0+HfNjAYPbL X-Received: by 2002:a62:4c0f:: with SMTP id z15-v6mr1397478pfa.110.1531151743546; Mon, 09 Jul 2018 08:55:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531151743; cv=none; d=google.com; s=arc-20160816; b=lmuI0raPX3Mtphid6fy4H8LI0KKebZyvd0CYf/5q5MSjt1Ab3pu2sTkBAX251uVdXM Ak6QtsW2njO8/Deonn2Noy7HRJKuC67L/2zkgwZpmmnNKiUH56vTZFEb/GeXgJT9rp3z nqd47/2p+39e4zsUD4JCSjy6xpS/Yhan2KpDY4TuItrR+n1dacWoxe6brlgyTE3+Zib1 MTBz3JGGwcUm5KcG2AC4B8iFJiSCAiaV+fr/X7U7URcb9RtZPk5lYBVjWcsSfa2KZj2d cv0nnLpWw5+Bajr6SKvVaGKIgR4YxFblRbdCJ1VxTZu+iVbcWv5wWhMlPtl+6gFFx564 Ka/A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=ciWHyLMikqH3wKENiDm/GxmXb1N461xZPfHB5KvcB1o=; b=nbBrHh178YlqR/DwBaB6saHnhrVjTK6RRVW1BPCfOHffD9GG75KiGgo8IMWM8Cnu+Q bc3sDnHOQatS8S4G7uaadRWBV9OUzjv7KPekdnoZ8d37DjMF2ITlgjjozR70qJXH0NMc hrTUmclPHzBH84PTRlfHTIkkU0wXUicgH7x+ExDBlhM/utb7vVVbbl06WC1+n0pZBW0+ fTXJr5hi4oVgX4UWCw+/3jJC8f1FG2bJTvVhBAhkEWiJpFe6uIHwUFcVh6w7X8N3ORWC +cKBTK2i14zggI8sk3mIFoggESIaQTGiHitEpJbDvqAbyG0k+wR8v1dMZl1b7xenr/Cz EpEw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="RpZIPx/b"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j30-v6si8423916pgm.26.2018.07.09.08.55.43; Mon, 09 Jul 2018 08:55:43 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="RpZIPx/b"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933714AbeGIPzk (ORCPT + 29 others); Mon, 9 Jul 2018 11:55:40 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:41187 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933328AbeGIPvL (ORCPT ); Mon, 9 Jul 2018 11:51:11 -0400 Received: by mail-wr1-f67.google.com with SMTP id j5-v6so4991932wrr.8 for ; Mon, 09 Jul 2018 08:51:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ciWHyLMikqH3wKENiDm/GxmXb1N461xZPfHB5KvcB1o=; b=RpZIPx/beUHRYti0cQ744TwtbMvSNQQPb29N9xR6xlvLjFNzkXijkASH1thcPbhx4X AteMQP0KOH3YQWSq/pwtEVJ6xxySNUrwSrwZkw3wWycGiuUScWXVfFuiieHZ4hY/jp1G 9fkUbuFQMqehVLNUclSBcO1q9gk7u+r+vRt6s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ciWHyLMikqH3wKENiDm/GxmXb1N461xZPfHB5KvcB1o=; b=FizC7UGzO+6aIHFYiI1wgeSXIFXNrwZH6VYZmUAzRUXr8W44VuopQleG2joRvJGuvJ cbRu08Ras4dYPCkUjW/RPJi9/zJSeoQE9AZIPOD9vr6d8uf3plqBzhb8Xo0wI3U4VPb3 jpoBZyjeJmlPDCUmHYUzv7Na1v0jm6rB/Hj8gFg4vGHVBEMP7P4nG5aHtJIIz3NsHo04 Uy4vC5WSGoZIwJJ1ySOEl1AnsoL0V7pXRkzkqUnynrFpZVTEV1IY8xTaxTpru3mmBmpp 8s7i+xkZ0ejjOqvYlCrH4th5qT1Qw+hwD8XB/Z8/IIFOgr5XHnGyN4im5/ofw59Vk4pj SYRw== X-Gm-Message-State: APt69E3tmS/diMPA0/6N+84ob4V/wxmVe5z4f0pnY9ua/wBkKUrmCmUo kyGKJGwFFHLsJnZLdLMQEFZ47w== X-Received: by 2002:a5d:4c4c:: with SMTP id n12-v6mr14513762wrt.71.1531151470880; Mon, 09 Jul 2018 08:51:10 -0700 (PDT) Received: from localhost.localdomain ([212.45.67.2]) by smtp.googlemail.com with ESMTPSA id o21-v6sm16229202wmg.28.2018.07.09.08.51.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Jul 2018 08:51:10 -0700 (PDT) From: Georgi Djakov To: linux-pm@vger.kernel.org, gregkh@linuxfoundation.org Cc: rjw@rjwysocki.net, robh+dt@kernel.org, mturquette@baylibre.com, khilman@baylibre.com, abailon@baylibre.com, vincent.guittot@linaro.org, skannan@codeaurora.org, bjorn.andersson@linaro.org, amit.kucheria@linaro.org, seansw@qti.qualcomm.com, daidavid1@codeaurora.org, evgreen@chromium.org, mka@chromium.org, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org, georgi.djakov@linaro.org Subject: [PATCH v6 2/8] dt-bindings: Introduce interconnect provider bindings Date: Mon, 9 Jul 2018 18:50:58 +0300 Message-Id: <20180709155104.25528-3-georgi.djakov@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180709155104.25528-1-georgi.djakov@linaro.org> References: <20180709155104.25528-1-georgi.djakov@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This binding is intended to represent the interconnect hardware present in some of the modern SoCs. Currently it consists only of a binding for the interconnect hardware devices (provider). Signed-off-by: Georgi Djakov --- .../bindings/interconnect/interconnect.txt | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/interconnect/interconnect.txt diff --git a/Documentation/devicetree/bindings/interconnect/interconnect.txt b/Documentation/devicetree/bindings/interconnect/interconnect.txt new file mode 100644 index 000000000000..6e2b2971b094 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/interconnect.txt @@ -0,0 +1,33 @@ +Interconnect Provider Device Tree Bindings +========================================= + +The purpose of this document is to define a common set of generic interconnect +providers/consumers properties. + + += interconnect providers = + +The interconnect provider binding is intended to represent the interconnect +controllers in the system. Each provider registers a set of interconnect +nodes, which expose the interconnect related capabilities of the interconnect +to consumer drivers. These capabilities can be throughput, latency, priority +etc. The consumer drivers set constraints on interconnect path (or endpoints) +depending on the use case. Interconnect providers can also be interconnect +consumers, such as in the case where two network-on-chip fabrics interface +directly + +Required properties: +- compatible : contains the interconnect provider compatible string +- #interconnect-cells : number of cells in a interconnect specifier needed to + encode the interconnect node id + +Example: + + snoc: snoc@580000 { + compatible = "qcom,msm8916-snoc"; + #interconnect-cells = <1>; + reg = <0x580000 0x14000>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&rpmcc RPM_SMD_SNOC_CLK>, + <&rpmcc RPM_SMD_SNOC_A_CLK>; + }; From patchwork Mon Jul 9 15:51:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Georgi Djakov X-Patchwork-Id: 141453 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2822283ljj; Mon, 9 Jul 2018 08:51:25 -0700 (PDT) X-Google-Smtp-Source: AAOMgpelqIPKS5Psq6HbNfvoj964g0rhGTuSDyChzG5oiyt5hKIOEuH3BJHlDVBmCcD2lcKTAliY X-Received: by 2002:a62:2605:: with SMTP id m5-v6mr21911987pfm.223.1531151485697; Mon, 09 Jul 2018 08:51:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531151485; cv=none; d=google.com; s=arc-20160816; b=Vvdcp3FqMYTMv2Obk0S5rvV9JvdG1yxm4InGnGAKgCyftJqhRgLtVNEoaixFrBrRnn 9ljzMFcFCbutAWRneJfoAjHd4GTQWqPvH/frGHrfwoPCjtMj1ghtHOsoDd8jbB3AGlPS 1BwRseFYrLqw24dVeg5KT4988H9x+hFUdH2gzc4oeeKGATUSkqO+sWoch8W4pqOoSQiw AcFxMYDaqTt90LZfq9n3eYcEceGoOp2GMiqnV6p2E8VxEU3uMWNL85wO3XD1ZZgHFxld bDBKHis+/4qgPXTDQXKOHijHZlBiUnF3Yq4XrFPGXnL2DBNJMRcmjs/rtY3nDWzlvpIs ta9A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=gSrXz+Ac1qZIXAw7/EQDjiJu46mhWeyLOdN6UJgkS6Y=; b=KHWCWJWKdpDUInO6EBulGdqU+WUmEe/WucoW7Lu8DvypmDa6SAO+KP5QzjFYqBV13y d0cCGZIotg4I/dZu/D2UsBtg4LyXgw2mJSl9i5gsHa8IhfQKakt5/GDdnV6ikpWd8BYL +MsSbe0VksasylbC3ZSDrrhLI+GPXgEeHWQRPr3R+kLNwvN1Fe0sse3BzAlH8TjZ5OZj L/lCvH0qLisRHm+/bTtvhEVtR3Qxf5q974/tOiru0Rev8bFjbXxe/z18miut/P5c0BLu amZaazj1iuzFb6wUIE5Q0MPMmAotFs2He0xJ3XPpxEn+95ZqjdK9LqbMNuysUhMwkm8T 71Eg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ACQfFKq2; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u190-v6si15265002pfb.325.2018.07.09.08.51.25; Mon, 09 Jul 2018 08:51:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ACQfFKq2; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933878AbeGIPvW (ORCPT + 30 others); Mon, 9 Jul 2018 11:51:22 -0400 Received: from mail-wr1-f66.google.com ([209.85.221.66]:33048 "EHLO mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933788AbeGIPvR (ORCPT ); Mon, 9 Jul 2018 11:51:17 -0400 Received: by mail-wr1-f66.google.com with SMTP id g6-v6so2600935wrp.0 for ; Mon, 09 Jul 2018 08:51:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=gSrXz+Ac1qZIXAw7/EQDjiJu46mhWeyLOdN6UJgkS6Y=; b=ACQfFKq21gWwbVr61FWYW5q6xim3vVzq8QLeFbP/Jd+yCI494iJGKbrUqR1GosgPGH QjtNeu1FcwdOklJ3gzTzJwIxD1uLqo6hL1fHKZotbQIAIg8wVpqE14FWdgyDJHvWhtID cLZ6tqKqntTwT/YmRAdGGRqh6sLrW0jIduC7Q= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=gSrXz+Ac1qZIXAw7/EQDjiJu46mhWeyLOdN6UJgkS6Y=; b=Ilp1H0hCiQFKZtAZww9qDC8VwhfkD+vEa2bZcoS6jWIS/q0eij5d68VoRyTRgiQZC8 EWdd70ff1Ib2jp1JFiqjE+YIU/TS2W4Wy7tcvwr9xVaZNPHzWHCcXuopAzoXuOrFTUo8 BUFj44iqPz1btPjg/b9+IPcz3zfCvcQ64xnZWdbT+4kd9hd3qIbL053Z3pz8NxmKuu73 e6ijwOqV5cMY58EZ+D4TGRoxYXeMDiRdfiuRYD7v94pCW+Nhf4QJCiFurqdKT4OvDYRN EWbT5aVDcAnzBQgM3f0vt1gTK2LczH3UvdwcbnD5sMDwgQdN885x0DDEVfqkWjEd9UpY qZzg== X-Gm-Message-State: APt69E16YoB9/u3+VefgOJk6QILJVPJ1dXV7T8PUBhZcFg7/rhWp2rIm XY4a1cQKNBWHsIMHnmaRUcNRTw== X-Received: by 2002:adf:b2f4:: with SMTP id g107-v6mr15979679wrd.53.1531151476267; Mon, 09 Jul 2018 08:51:16 -0700 (PDT) Received: from localhost.localdomain ([212.45.67.2]) by smtp.googlemail.com with ESMTPSA id o21-v6sm16229202wmg.28.2018.07.09.08.51.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Jul 2018 08:51:15 -0700 (PDT) From: Georgi Djakov To: linux-pm@vger.kernel.org, gregkh@linuxfoundation.org Cc: rjw@rjwysocki.net, robh+dt@kernel.org, mturquette@baylibre.com, khilman@baylibre.com, abailon@baylibre.com, vincent.guittot@linaro.org, skannan@codeaurora.org, bjorn.andersson@linaro.org, amit.kucheria@linaro.org, seansw@qti.qualcomm.com, daidavid1@codeaurora.org, evgreen@chromium.org, mka@chromium.org, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org, georgi.djakov@linaro.org Subject: [PATCH v6 5/8] dt-bindings: interconnect: Document qcom, msm8916 NoC bindings Date: Mon, 9 Jul 2018 18:51:01 +0300 Message-Id: <20180709155104.25528-6-georgi.djakov@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180709155104.25528-1-georgi.djakov@linaro.org> References: <20180709155104.25528-1-georgi.djakov@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Document the device-tree bindings Network-On-Chip interconnect driver for Qualcomm msm8916 platforms. Signed-off-by: Georgi Djakov --- .../bindings/interconnect/qcom-msm8916.txt | 39 ++ include/dt-bindings/interconnect/qcom.h | 350 ++++++++++++++++++ 2 files changed, 389 insertions(+) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom-msm8916.txt create mode 100644 include/dt-bindings/interconnect/qcom.h diff --git a/Documentation/devicetree/bindings/interconnect/qcom-msm8916.txt b/Documentation/devicetree/bindings/interconnect/qcom-msm8916.txt new file mode 100644 index 000000000000..f309eaed3d19 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom-msm8916.txt @@ -0,0 +1,39 @@ +Qualcomm MSM8916 Network-On-Chip interconnect driver binding +---------------------------------------------------- + +Required properties : +- compatible : shall contain only one of the following: + "qcom,msm8916-bimc" + "qcom,msm8916-pnoc" + "qcom,msm8916-snoc" +- #interconnect-cells : should contain 1 +- reg : shall contain base register location and length + +Optional properties : +clocks : list of phandles and specifiers to all interconnect bus clocks +clock-names : clock names should include both "bus_clk" and "bus_a_clk" + +Examples: + + snoc: snoc@580000 { + compatible = "qcom,msm8916-snoc"; + #interconnect-cells = <1>; + reg = <0x580000 0x14000>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&rpmcc RPM_SMD_SNOC_CLK>, <&rpmcc RPM_SMD_SNOC_A_CLK>; + }; + bimc: bimc@400000 { + compatible = "qcom,msm8916-bimc"; + #interconnect-cells = <1>; + reg = <0x400000 0x62000>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&rpmcc RPM_SMD_BIMC_CLK>, <&rpmcc RPM_SMD_BIMC_A_CLK>; + }; + pnoc: pnoc@500000 { + compatible = "qcom,msm8916-pnoc"; + #interconnect-cells = <1>; + reg = <0x500000 0x11000>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&rpmcc RPM_SMD_PCNOC_CLK>, <&rpmcc RPM_SMD_PCNOC_A_CLK>; + }; + diff --git a/include/dt-bindings/interconnect/qcom.h b/include/dt-bindings/interconnect/qcom.h new file mode 100644 index 000000000000..2cd378d2f575 --- /dev/null +++ b/include/dt-bindings/interconnect/qcom.h @@ -0,0 +1,350 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Qualcomm interconnect IDs + * + * Copyright (c) 2018, Linaro Ltd. + * Author: Georgi Djakov + */ + +#ifndef __QCOM_INTERCONNECT_IDS_H +#define __QCOM_INTERCONNECT_IDS_H + +#define FAB_BIMC 0 +#define FAB_SYS_NOC 1024 +#define FAB_MMSS_NOC 2048 +#define FAB_OCMEM_NOC 3072 +#define FAB_PERIPH_NOC 4096 +#define FAB_CONFIG_NOC 5120 +#define FAB_OCMEM_VNOC 6144 + +#define MASTER_AMPSS_M0 1 +#define MASTER_AMPSS_M1 2 +#define APPSS_MASTER_FAB_MMSS 3 +#define APPSS_MASTER_FAB_SYSTEM 4 +#define SYSTEM_MASTER_FAB_APPSS 5 +#define MASTER_SPS 6 +#define MASTER_ADM_PORT0 7 +#define MASTER_ADM_PORT1 8 +#define SYSTEM_MASTER_ADM1_PORT0 9 +#define MASTER_ADM1_PORT1 10 +#define MASTER_LPASS_PROC 11 +#define MASTER_MSS_PROCI 12 +#define MASTER_MSS_PROCD 13 +#define MASTER_MSS_MDM_PORT0 14 +#define MASTER_LPASS 15 +#define SYSTEM_MASTER_CPSS_FPB 16 +#define SYSTEM_MASTER_SYSTEM_FPB 17 +#define SYSTEM_MASTER_MMSS_FPB 18 +#define MASTER_ADM1_CI 19 +#define MASTER_ADM0_CI 20 +#define MASTER_MSS_MDM_PORT1 21 +#define MASTER_MDP_PORT0 22 +#define MASTER_MDP_PORT1 23 +#define MMSS_MASTER_ADM1_PORT0 24 +#define MASTER_ROTATOR 25 +#define MASTER_GRAPHICS_3D 26 +#define MASTER_JPEG_DEC 27 +#define MASTER_GRAPHICS_2D_CORE0 28 +#define MASTER_VFE 29 +#define MASTER_VPE 30 +#define MASTER_JPEG_ENC 31 +#define MASTER_GRAPHICS_2D_CORE1 32 +#define MMSS_MASTER_APPS_FAB 33 +#define MASTER_HD_CODEC_PORT0 34 +#define MASTER_HD_CODEC_PORT1 35 +#define MASTER_SPDM 36 +#define MASTER_RPM 37 +#define MASTER_MSS 38 +#define MASTER_RIVA 39 +#define SYSTEM_MASTER_UNUSED_6 40 +#define MASTER_MSS_SW_PROC 41 +#define MASTER_MSS_FW_PROC 42 +#define MMSS_MASTER_UNUSED_2 43 +#define MASTER_GSS_NAV 44 +#define MASTER_PCIE 45 +#define MASTER_SATA 46 +#define MASTER_CRYPTO 47 +#define MASTER_VIDEO_CAP 48 +#define MASTER_GRAPHICS_3D_PORT1 49 +#define MASTER_VIDEO_ENC 50 +#define MASTER_VIDEO_DEC 51 +#define MASTER_LPASS_AHB 52 +#define MASTER_QDSS_BAM 53 +#define MASTER_SNOC_CFG 54 +#define MASTER_CRYPTO_CORE0 55 +#define MASTER_CRYPTO_CORE1 56 +#define MASTER_MSS_NAV 57 +#define MASTER_OCMEM_DMA 58 +#define MASTER_WCSS 59 +#define MASTER_QDSS_ETR 60 +#define MASTER_USB3 61 +#define MASTER_JPEG 62 +#define MASTER_VIDEO_P0 63 +#define MASTER_VIDEO_P1 64 +#define MASTER_MSS_PROC 65 +#define MASTER_JPEG_OCMEM 66 +#define MASTER_MDP_OCMEM 67 +#define MASTER_VIDEO_P0_OCMEM 68 +#define MASTER_VIDEO_P1_OCMEM 69 +#define MASTER_VFE_OCMEM 70 +#define MASTER_CNOC_ONOC_CFG 71 +#define MASTER_RPM_INST 72 +#define MASTER_RPM_DATA 73 +#define MASTER_RPM_SYS 74 +#define MASTER_DEHR 75 +#define MASTER_QDSS_DAP 76 +#define MASTER_TIC 77 +#define MASTER_SDCC_1 78 +#define MASTER_SDCC_3 79 +#define MASTER_SDCC_4 80 +#define MASTER_SDCC_2 81 +#define MASTER_TSIF 82 +#define MASTER_BAM_DMA 83 +#define MASTER_BLSP_2 84 +#define MASTER_USB_HSIC 85 +#define MASTER_BLSP_1 86 +#define MASTER_USB_HS 87 +#define MASTER_PNOC_CFG 88 +#define MASTER_V_OCMEM_GFX3D 89 +#define MASTER_IPA 90 +#define MASTER_QPIC 91 +#define MASTER_MDPE 92 +#define MASTER_USB_HS2 93 +#define MASTER_VPU 94 +#define MASTER_UFS 95 +#define MASTER_BCAST 96 +#define MASTER_CRYPTO_CORE2 97 +#define MASTER_EMAC 98 +#define MASTER_VPU_1 99 +#define MASTER_PCIE_1 100 +#define MASTER_USB3_1 101 +#define MASTER_CNOC_MNOC_MMSS_CFG 102 +#define MASTER_CNOC_MNOC_CFG 103 +#define MASTER_TCU_0 104 +#define MASTER_TCU_1 105 +#define MASTER_CPP 106 +#define MASTER_AUDIO 107 + +#define SNOC_MM_INT_0 10000 +#define SNOC_MM_INT_1 10001 +#define SNOC_MM_INT_2 10002 +#define SNOC_MM_INT_BIMC 10003 +#define SNOC_INT_0 10004 +#define SNOC_INT_1 10005 +#define SNOC_INT_BIMC 10006 +#define SNOC_BIMC_0_MAS 10007 +#define SNOC_BIMC_1_MAS 10008 +#define SNOC_QDSS_INT 10009 +#define PNOC_SNOC_MAS 10010 +#define PNOC_SNOC_SLV 10011 +#define PNOC_INT_0 10012 +#define PNOC_INT_1 10013 +#define PNOC_M_0 10014 +#define PNOC_M_1 10015 +#define BIMC_SNOC_MAS 10016 +#define BIMC_SNOC_SLV 10017 +#define PNOC_SLV_0 10018 +#define PNOC_SLV_1 10019 +#define PNOC_SLV_2 10020 +#define PNOC_SLV_3 10021 +#define PNOC_SLV_4 10022 +#define PNOC_SLV_8 10023 +#define PNOC_SLV_9 10024 +#define SNOC_BIMC_0_SLV 10025 +#define SNOC_BIMC_1_SLV 10026 +#define MNOC_BIMC_MAS 10027 +#define MNOC_BIMC_SLV 10028 +#define BIMC_MNOC_MAS 10029 +#define BIMC_MNOC_SLV 10030 +#define SNOC_BIMC_MAS 10031 +#define SNOC_BIMC_SLV 10032 +#define CNOC_SNOC_MAS 10033 +#define CNOC_SNOC_SLV 10034 +#define SNOC_CNOC_MAS 10035 +#define SNOC_CNOC_SLV 10036 +#define OVNOC_SNOC_MAS 10037 +#define OVNOC_SNOC_SLV 10038 +#define SNOC_OVNOC_MAS 10039 +#define SNOC_OVNOC_SLV 10040 +#define SNOC_PNOC_MAS 10041 +#define SNOC_PNOC_SLV 10042 +#define BIMC_INT_APPS_EBI 10043 +#define BIMC_INT_APPS_SNOC 10044 +#define SNOC_BIMC_2_MAS 10045 +#define SNOC_BIMC_2_SLV 10046 +#define PNOC_SLV_5 10047 +#define PNOC_SLV_7 10048 +#define PNOC_INT_2 10049 +#define PNOC_INT_3 10050 +#define PNOC_INT_4 10051 +#define PNOC_INT_5 10052 +#define PNOC_INT_6 10053 +#define PNOC_INT_7 10054 + +#define SLAVE_EBI_CH0 512 +#define SLAVE_EBI_CH1 513 +#define SLAVE_AMPSS_L2 514 +#define APPSS_SLAVE_FAB_MMSS 515 +#define APPSS_SLAVE_FAB_SYSTEM 516 +#define SYSTEM_SLAVE_FAB_APPS 517 +#define SLAVE_SPS 518 +#define SLAVE_SYSTEM_IMEM 519 +#define SLAVE_AMPSS 520 +#define SLAVE_MSS 521 +#define SLAVE_LPASS 522 +#define SYSTEM_SLAVE_CPSS_FPB 523 +#define SYSTEM_SLAVE_SYSTEM_FPB 524 +#define SYSTEM_SLAVE_MMSS_FPB 525 +#define SLAVE_CORESIGHT 526 +#define SLAVE_RIVA 527 +#define SLAVE_SMI 528 +#define MMSS_SLAVE_FAB_APPS 529 +#define MMSS_SLAVE_FAB_APPS_1 530 +#define SLAVE_MM_IMEM 531 +#define SLAVE_CRYPTO 532 +#define SLAVE_SPDM 533 +#define SLAVE_RPM 534 +#define SLAVE_RPM_MSG_RAM 535 +#define SLAVE_MPM 536 +#define SLAVE_PMIC1_SSBI1_A 537 +#define SLAVE_PMIC1_SSBI1_B 538 +#define SLAVE_PMIC1_SSBI1_C 539 +#define SLAVE_PMIC2_SSBI2_A 540 +#define SLAVE_PMIC2_SSBI2_B 541 +#define SLAVE_GSBI1_UART 542 +#define SLAVE_GSBI2_UART 543 +#define SLAVE_GSBI3_UART 544 +#define SLAVE_GSBI4_UART 545 +#define SLAVE_GSBI5_UART 546 +#define SLAVE_GSBI6_UART 547 +#define SLAVE_GSBI7_UART 548 +#define SLAVE_GSBI8_UART 549 +#define SLAVE_GSBI9_UART 550 +#define SLAVE_GSBI10_UART 551 +#define SLAVE_GSBI11_UART 552 +#define SLAVE_GSBI12_UART 553 +#define SLAVE_GSBI1_QUP 554 +#define SLAVE_GSBI2_QUP 555 +#define SLAVE_GSBI3_QUP 556 +#define SLAVE_GSBI4_QUP 557 +#define SLAVE_GSBI5_QUP 558 +#define SLAVE_GSBI6_QUP 559 +#define SLAVE_GSBI7_QUP 560 +#define SLAVE_GSBI8_QUP 561 +#define SLAVE_GSBI9_QUP 562 +#define SLAVE_GSBI10_QUP 563 +#define SLAVE_GSBI11_QUP 564 +#define SLAVE_GSBI12_QUP 565 +#define SLAVE_EBI2_NAND 566 +#define SLAVE_EBI2_CS0 567 +#define SLAVE_EBI2_CS1 568 +#define SLAVE_EBI2_CS2 569 +#define SLAVE_EBI2_CS3 570 +#define SLAVE_EBI2_CS4 571 +#define SLAVE_EBI2_CS5 572 +#define SLAVE_USB_FS1 573 +#define SLAVE_USB_FS2 574 +#define SLAVE_TSIF 575 +#define SLAVE_MSM_TSSC 576 +#define SLAVE_MSM_PDM 577 +#define SLAVE_MSM_DIMEM 578 +#define SLAVE_MSM_TCSR 579 +#define SLAVE_MSM_PRNG 580 +#define SLAVE_GSS 581 +#define SLAVE_SATA 582 +#define SLAVE_USB3 583 +#define SLAVE_WCSS 584 +#define SLAVE_OCIMEM 585 +#define SLAVE_SNOC_OCMEM 586 +#define SLAVE_SERVICE_SNOC 587 +#define SLAVE_QDSS_STM 588 +#define SLAVE_CAMERA_CFG 589 +#define SLAVE_DISPLAY_CFG 590 +#define SLAVE_OCMEM_CFG 591 +#define SLAVE_CPR_CFG 592 +#define SLAVE_CPR_XPU_CFG 593 +#define SLAVE_MISC_CFG 594 +#define SLAVE_MISC_XPU_CFG 595 +#define SLAVE_VENUS_CFG 596 +#define SLAVE_MISC_VENUS_CFG 597 +#define SLAVE_GRAPHICS_3D_CFG 598 +#define SLAVE_MMSS_CLK_CFG 599 +#define SLAVE_MMSS_CLK_XPU_CFG 600 +#define SLAVE_MNOC_MPU_CFG 601 +#define SLAVE_ONOC_MPU_CFG 602 +#define SLAVE_SERVICE_MNOC 603 +#define SLAVE_OCMEM 604 +#define SLAVE_SERVICE_ONOC 605 +#define SLAVE_SDCC_1 606 +#define SLAVE_SDCC_3 607 +#define SLAVE_SDCC_2 608 +#define SLAVE_SDCC_4 609 +#define SLAVE_BAM_DMA 610 +#define SLAVE_BLSP_2 611 +#define SLAVE_USB_HSIC 612 +#define SLAVE_BLSP_1 613 +#define SLAVE_USB_HS 614 +#define SLAVE_PDM 615 +#define SLAVE_PERIPH_APU_CFG 616 +#define SLAVE_PNOC_MPU_CFG 617 +#define SLAVE_PRNG 618 +#define SLAVE_SERVICE_PNOC 619 +#define SLAVE_CLK_CTL 620 +#define SLAVE_CNOC_MSS 621 +#define SLAVE_SECURITY 622 +#define SLAVE_TCSR 623 +#define SLAVE_TLMM 624 +#define SLAVE_CRYPTO_0_CFG 625 +#define SLAVE_CRYPTO_1_CFG 626 +#define SLAVE_IMEM_CFG 627 +#define SLAVE_MESSAGE_RAM 628 +#define SLAVE_BIMC_CFG 629 +#define SLAVE_BOOT_ROM 630 +#define SLAVE_CNOC_MNOC_MMSS_CFG 631 +#define SLAVE_PMIC_ARB 632 +#define SLAVE_SPDM_WRAPPER 633 +#define SLAVE_DEHR_CFG 634 +#define SLAVE_QDSS_CFG 635 +#define SLAVE_RBCPR_CFG 636 +#define SLAVE_RBCPR_QDSS_APU_CFG 637 +#define SLAVE_SNOC_MPU_CFG 638 +#define SLAVE_CNOC_ONOC_CFG 639 +#define SLAVE_CNOC_MNOC_CFG 640 +#define SLAVE_PNOC_CFG 641 +#define SLAVE_SNOC_CFG 642 +#define SLAVE_EBI1_DLL_CFG 643 +#define SLAVE_PHY_APU_CFG 644 +#define SLAVE_EBI1_PHY_CFG 645 +#define SLAVE_SERVICE_CNOC 646 +#define SLAVE_IPS_CFG 647 +#define SLAVE_QPIC 648 +#define SLAVE_DSI_CFG 649 +#define SLAVE_UFS_CFG 650 +#define SLAVE_RBCPR_CX_CFG 651 +#define SLAVE_RBCPR_MX_CFG 652 +#define SLAVE_PCIE_CFG 653 +#define SLAVE_USB_PHYS_CFG 654 +#define SLAVE_VIDEO_CAP_CFG 655 +#define SLAVE_AVSYNC_CFG 656 +#define SLAVE_CRYPTO_2_CFG 657 +#define SLAVE_VPU_CFG 658 +#define SLAVE_BCAST_CFG 659 +#define SLAVE_KLM_CFG 660 +#define SLAVE_GENI_IR_CFG 661 +#define SLAVE_OCMEM_GFX 662 +#define SLAVE_CATS_128 663 +#define SLAVE_OCMEM_64 664 +#define SLAVE_PCIE_0 665 +#define SLAVE_PCIE_1 666 +#define SLAVE_PCIE_0_CFG 667 +#define SLAVE_PCIE_1_CFG 668 +#define SLAVE_SRVC_MNOC 669 +#define SLAVE_USB_HS2 670 +#define SLAVE_AUDIO 671 +#define SLAVE_TCU 672 +#define SLAVE_APPSS 673 +#define SLAVE_PCIE_PARF 674 +#define SLAVE_USB3_PHY_CFG 675 +#define SLAVE_IPA_CFG 676 + +#endif From patchwork Mon Jul 9 15:51:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Georgi Djakov X-Patchwork-Id: 141454 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2822414ljj; Mon, 9 Jul 2018 08:51:32 -0700 (PDT) X-Google-Smtp-Source: AAOMgpdMeBbi1zukujwA0Oy8RxRsI8TE07mD3cUV0POsDGc0xah6QpkrUWc3+vJFRjWjqwDS7CE5 X-Received: by 2002:a62:398c:: with SMTP id u12-v6mr22006289pfj.9.1531151492721; Mon, 09 Jul 2018 08:51:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531151492; cv=none; d=google.com; s=arc-20160816; b=D9zISRLc+DnI4pjOYEJXYsenseoaPJo3yZsfx6VfRPRK2rzrp5echMHJUHwRLGnut9 W6k4uXBhO7k0yIUfsl5QNkwOBJkTClS01rihhJUaR1b2i2vgQK9kvnEPdHmuEmvgm+8G /XrLaKH1iBQWMBNk8EtgzXNkIYaRLQ+mEfCabIMJI/m42b0JoqY8Dq3kCRrL4x5US1Nq V75ToFjoT7vWM4VlvO16PZgYeH9vFWjMGtKg1fUNgurXMsVr9I5IzG+FyhYc0kzGnh7q Nna+YBhGEfv1mbZL/GdQ8v24xwLd77GrB4tuBVX/CqGpbHQEbYO5iIHw6fDVJdvYr+D3 afGg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=DNr9YSOIuqljr+o8vfQtsz/Q2VakflKl3VDBWnrqcHQ=; b=0eZY+Evp8OD5PkD796iLVE3r1lX4GglmZDEZeFqwmz0yvMBqQUOMySyFSMXpfEw0Oz xICXpVmzjFP3qSVgDGJIeeo/yeLvnr3HH/2wmGKsi9aT4rQuoira/c43YX3BXMGI4ZRt AXDCfkbtUfwMlasODM0Yysc57X1FYOHBf+h+Zsvlz0e1P7aNcpnINvu9BB19AMzU4jiS ubXaUd/W/cNY6w1I1r/+K2SZ6NzFc2wyblKwp81e5GaSI88m83kOSCYf/2XukNYw/hNt KQb3ZaviP0KX9s3o44zYXRmszay9Dug+SZf+2N5jvGojS1mVeAJ31Eezx6nLpOqgrIYF /Dig== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=EoAlAP3p; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u190-v6si15265002pfb.325.2018.07.09.08.51.32; Mon, 09 Jul 2018 08:51:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=EoAlAP3p; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933897AbeGIPvb (ORCPT + 30 others); Mon, 9 Jul 2018 11:51:31 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:37542 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933868AbeGIPvW (ORCPT ); Mon, 9 Jul 2018 11:51:22 -0400 Received: by mail-wm0-f65.google.com with SMTP id n17-v6so21296126wmh.2 for ; Mon, 09 Jul 2018 08:51:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DNr9YSOIuqljr+o8vfQtsz/Q2VakflKl3VDBWnrqcHQ=; b=EoAlAP3pfjTeVe6ZNkzjP9lgC9RhNbA88PpqZNF6u8ls6UWmSXfzlUpNPIRpLWpHEh D6jgFZfv58HQOYc8wZTtz7c6lJhGJAIRH+AOlV0GS+W9hIAZ5Z9Gv3f3YY00DdHIX2M6 6G3aWMskqCnxsW+HUYAMSZMTBUpUyGT6y/P5A= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=DNr9YSOIuqljr+o8vfQtsz/Q2VakflKl3VDBWnrqcHQ=; b=VYOully7n49q5mDpNzlgoD8hRPJ5P9iPkt0U97yeVqvpFtOVbguI/hS3l4B0XFe40h QpLTW9+5ViYTlHZmiUAZkxAbmDsEWrZWKQnzDGbe3PzjTINxSuBPFeUqmlf1V4TGO/GE 0h4rIo1isT2SyMrqZMVHUFr0vWQMEVS/B+XFftVpttZFaxydCDuypcHzZakQzHXrJwRP 7oICG7Fg0r6hgbF2N+zaxGjTJ0sOY+BKLMVpPvnEKE9OhzdkaGm4ADG3HRW36d0B2jcR QodvKFFDZdEU1MiTZ3InX2nBoUU8Dv9i1p4jkBnA9wX93AUzEnr4WIAXGUsw7AZNNNF5 cJwA== X-Gm-Message-State: APt69E2t4m+7c+1TxGqy1OXrKZ+EW8mqZfLZc+wzjNtG9ReXLOMnwFH0 qD0kADAtDmPLSTCC9MII2bk3kA== X-Received: by 2002:a1c:f906:: with SMTP id x6-v6mr12363995wmh.63.1531151481491; Mon, 09 Jul 2018 08:51:21 -0700 (PDT) Received: from localhost.localdomain ([212.45.67.2]) by smtp.googlemail.com with ESMTPSA id o21-v6sm16229202wmg.28.2018.07.09.08.51.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Jul 2018 08:51:20 -0700 (PDT) From: Georgi Djakov To: linux-pm@vger.kernel.org, gregkh@linuxfoundation.org Cc: rjw@rjwysocki.net, robh+dt@kernel.org, mturquette@baylibre.com, khilman@baylibre.com, abailon@baylibre.com, vincent.guittot@linaro.org, skannan@codeaurora.org, bjorn.andersson@linaro.org, amit.kucheria@linaro.org, seansw@qti.qualcomm.com, daidavid1@codeaurora.org, evgreen@chromium.org, mka@chromium.org, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org, georgi.djakov@linaro.org Subject: [PATCH v6 8/8] interconnect: Allow endpoints translation via DT Date: Mon, 9 Jul 2018 18:51:04 +0300 Message-Id: <20180709155104.25528-9-georgi.djakov@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180709155104.25528-1-georgi.djakov@linaro.org> References: <20180709155104.25528-1-georgi.djakov@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Currently we support only platform data for specifying the interconnect endpoints. As now the endpoints are hard-coded into the consumer driver this may lead to complications when a single driver is used by multiple SoCs, which may have different interconnect topology. To avoid cluttering the consumer drivers, introduce a translation function to help us get the board specific interconnect data from device-tree. Signed-off-by: Georgi Djakov --- drivers/interconnect/core.c | 62 ++++++++++++++++++++++++++++++++++++ include/linux/interconnect.h | 7 ++++ 2 files changed, 69 insertions(+) diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c index 3f5001f51bb7..5817f081f6cf 100644 --- a/drivers/interconnect/core.c +++ b/drivers/interconnect/core.c @@ -16,6 +16,7 @@ #include #include #include +#include #include static DEFINE_IDR(icc_idr); @@ -294,6 +295,67 @@ static int apply_constraints(struct icc_path *path) return ret; } +struct icc_path *of_icc_get(struct device *dev, const char *name) +{ + struct device_node *np = NULL; + struct of_phandle_args src_args, dst_args; + u32 src_id, dst_id; + int idx = 0; + int ret; + + if (!dev || !dev->of_node) + return ERR_PTR(-ENODEV); + + np = dev->of_node; + + /* + * When the consumer DT node do not have "interconnects" property + * return a NULL path to skip setting constraints. + */ + if (!of_find_property(np, "interconnects", NULL)) + return NULL; + + /* + * We use a combination of phandle and specifier for endpoint. For now + * lets support only global ids and extend this is the future if needed + * without breaking DT compatibility. + */ + if (name) { + idx = of_property_match_string(np, "interconnect-names", name); + if (idx < 0) + return ERR_PTR(idx); + } + + ret = of_parse_phandle_with_args(np, "interconnects", + "#interconnect-cells", idx * 2, + &src_args); + if (ret) + return ERR_PTR(ret); + + of_node_put(src_args.np); + + if (!src_args.args_count || src_args.args_count > 1) + return ERR_PTR(-EINVAL); + + src_id = src_args.args[0]; + + ret = of_parse_phandle_with_args(np, "interconnects", + "#interconnect-cells", idx * 2 + 1, + &dst_args); + if (ret) + return ERR_PTR(ret); + + of_node_put(dst_args.np); + + if (!dst_args.args_count || dst_args.args_count > 1) + return ERR_PTR(-EINVAL); + + dst_id = dst_args.args[0]; + + return icc_get(dev, src_id, dst_id); +} +EXPORT_SYMBOL_GPL(of_icc_get); + /** * icc_set() - set constraints on an interconnect path between two endpoints * @path: reference to the path returned by icc_get() diff --git a/include/linux/interconnect.h b/include/linux/interconnect.h index 593215371fd6..ae6744da9bc2 100644 --- a/include/linux/interconnect.h +++ b/include/linux/interconnect.h @@ -17,6 +17,7 @@ struct device; struct icc_path *icc_get(struct device *dev, const int src_id, const int dst_id); +struct icc_path *of_icc_get(struct device *dev, const char *name); void icc_put(struct icc_path *path); int icc_set(struct icc_path *path, u32 avg_bw, u32 peak_bw); @@ -28,6 +29,12 @@ static inline struct icc_path *icc_get(struct device *dev, const int src_id, return NULL; } +static inline struct icc_path *of_icc_get(struct device *dev, + const char *name) +{ + return NULL; +} + static inline void icc_put(struct icc_path *path) { }