Skip to content

Commit

Permalink
Merge tag 'icc-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/djakov/icc into char-misc-next

Georgi writes:

interconnect changes for 5.12

Here are the interconnect changes for the 5.12-rc1 merge window
consisting of driver updates.

Driver changes:
- Refactoring and consolidation of drivers.
- New driver for MSM8939 platforms.
- New driver for SDX55 platforms.

Signed-off-by: Georgi Djakov <djakov@kernel.org>

* tag 'icc-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/djakov/icc:
  interconnect: qcom: Add SDX55 interconnect provider driver
  dt-bindings: interconnect: Add Qualcomm SDX55 DT bindings
  interconnect: qcom: Add MSM8939 interconnect provider driver
  dt-bindings: interconnect: Add Qualcomm MSM8939 DT bindings
  dt-bindings: interconnect: single yaml file for RPM interconnect drivers
  interconnect: qcom: qcs404: use shared code
  interconnect: qcom: Consolidate interconnect RPM support
  • Loading branch information
Greg Kroah-Hartman committed Feb 5, 2021
2 parents 920fd8a + 6715ea0 commit 5157110
Show file tree
Hide file tree
Showing 14 changed files with 1,286 additions and 550 deletions.
77 changes: 0 additions & 77 deletions Documentation/devicetree/bindings/interconnect/qcom,qcs404.yaml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/interconnect/qcom,msm8916.yaml#
$id: http://devicetree.org/schemas/interconnect/qcom,rpm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Qualcomm MSM8916 Network-On-Chip interconnect
title: Qualcomm RPM Network-On-Chip Interconnect

maintainers:
- Georgi Djakov <georgi.djakov@linaro.org>

description: |
The Qualcomm MSM8916 interconnect providers support adjusting the
bandwidth requirements between the various NoC fabrics.
RPM interconnect providers support system bandwidth requirements through
RPM processor. The provider is able to communicate with the RPM through
the RPM shared memory device.
properties:
reg:
maxItems: 1

compatible:
enum:
- qcom,msm8916-bimc
- qcom,msm8916-pcnoc
- qcom,msm8916-snoc

reg:
maxItems: 1
- qcom,msm8939-bimc
- qcom,msm8939-pcnoc
- qcom,msm8939-snoc
- qcom,msm8939-snoc-mm
- qcom,qcs404-bimc
- qcom,qcs404-pcnoc
- qcom,qcs404-snoc

'#interconnect-cells':
const: 1
Expand Down
4 changes: 4 additions & 0 deletions Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ properties:
- qcom,sdm845-mem-noc
- qcom,sdm845-mmss-noc
- qcom,sdm845-system-noc
- qcom,sdx55-ipa-virt
- qcom,sdx55-mc-virt
- qcom,sdx55-mem-noc
- qcom,sdx55-system-noc
- qcom,sm8150-aggre1-noc
- qcom,sm8150-aggre2-noc
- qcom,sm8150-camnoc-noc
Expand Down
18 changes: 18 additions & 0 deletions drivers/interconnect/qcom/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ config INTERCONNECT_QCOM_MSM8916
This is a driver for the Qualcomm Network-on-Chip on msm8916-based
platforms.

config INTERCONNECT_QCOM_MSM8939
tristate "Qualcomm MSM8939 interconnect driver"
depends on INTERCONNECT_QCOM
depends on QCOM_SMD_RPM
select INTERCONNECT_QCOM_SMD_RPM
help
This is a driver for the Qualcomm Network-on-Chip on msm8939-based
platforms.

config INTERCONNECT_QCOM_MSM8974
tristate "Qualcomm MSM8974 interconnect driver"
depends on INTERCONNECT_QCOM
Expand Down Expand Up @@ -74,6 +83,15 @@ config INTERCONNECT_QCOM_SDM845
This is a driver for the Qualcomm Network-on-Chip on sdm845-based
platforms.

config INTERCONNECT_QCOM_SDX55
tristate "Qualcomm SDX55 interconnect driver"
depends on INTERCONNECT_QCOM_RPMH_POSSIBLE
select INTERCONNECT_QCOM_RPMH
select INTERCONNECT_QCOM_BCM_VOTER
help
This is a driver for the Qualcomm Network-on-Chip on sdx55-based
platforms.

config INTERCONNECT_QCOM_SM8150
tristate "Qualcomm SM8150 interconnect driver"
depends on INTERCONNECT_QCOM_RPMH_POSSIBLE
Expand Down
6 changes: 5 additions & 1 deletion drivers/interconnect/qcom/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,28 @@

icc-bcm-voter-objs := bcm-voter.o
qnoc-msm8916-objs := msm8916.o
qnoc-msm8939-objs := msm8939.o
qnoc-msm8974-objs := msm8974.o
icc-osm-l3-objs := osm-l3.o
qnoc-qcs404-objs := qcs404.o
icc-rpmh-obj := icc-rpmh.o
qnoc-sc7180-objs := sc7180.o
qnoc-sdm845-objs := sdm845.o
qnoc-sdx55-objs := sdx55.o
qnoc-sm8150-objs := sm8150.o
qnoc-sm8250-objs := sm8250.o
icc-smd-rpm-objs := smd-rpm.o
icc-smd-rpm-objs := smd-rpm.o icc-rpm.o

obj-$(CONFIG_INTERCONNECT_QCOM_BCM_VOTER) += icc-bcm-voter.o
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8916) += qnoc-msm8916.o
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8939) += qnoc-msm8939.o
obj-$(CONFIG_INTERCONNECT_QCOM_MSM8974) += qnoc-msm8974.o
obj-$(CONFIG_INTERCONNECT_QCOM_OSM_L3) += icc-osm-l3.o
obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o
obj-$(CONFIG_INTERCONNECT_QCOM_RPMH) += icc-rpmh.o
obj-$(CONFIG_INTERCONNECT_QCOM_SC7180) += qnoc-sc7180.o
obj-$(CONFIG_INTERCONNECT_QCOM_SDM845) += qnoc-sdm845.o
obj-$(CONFIG_INTERCONNECT_QCOM_SDX55) += qnoc-sdx55.o
obj-$(CONFIG_INTERCONNECT_QCOM_SM8150) += qnoc-sm8150.o
obj-$(CONFIG_INTERCONNECT_QCOM_SM8250) += qnoc-sm8250.o
obj-$(CONFIG_INTERCONNECT_QCOM_SMD_RPM) += icc-smd-rpm.o
191 changes: 191 additions & 0 deletions drivers/interconnect/qcom/icc-rpm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2020 Linaro Ltd
*/

#include <linux/clk.h>
#include <linux/device.h>
#include <linux/interconnect-provider.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include "smd-rpm.h"
#include "icc-rpm.h"

static int qcom_icc_set(struct icc_node *src, struct icc_node *dst)
{
struct qcom_icc_provider *qp;
struct qcom_icc_node *qn;
struct icc_provider *provider;
struct icc_node *n;
u64 sum_bw;
u64 max_peak_bw;
u64 rate;
u32 agg_avg = 0;
u32 agg_peak = 0;
int ret, i;

qn = src->data;
provider = src->provider;
qp = to_qcom_provider(provider);

list_for_each_entry(n, &provider->nodes, node_list)
provider->aggregate(n, 0, n->avg_bw, n->peak_bw,
&agg_avg, &agg_peak);

sum_bw = icc_units_to_bps(agg_avg);
max_peak_bw = icc_units_to_bps(agg_peak);

/* send bandwidth request message to the RPM processor */
if (qn->mas_rpm_id != -1) {
ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE,
RPM_BUS_MASTER_REQ,
qn->mas_rpm_id,
sum_bw);
if (ret) {
pr_err("qcom_icc_rpm_smd_send mas %d error %d\n",
qn->mas_rpm_id, ret);
return ret;
}
}

if (qn->slv_rpm_id != -1) {
ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE,
RPM_BUS_SLAVE_REQ,
qn->slv_rpm_id,
sum_bw);
if (ret) {
pr_err("qcom_icc_rpm_smd_send slv error %d\n",
ret);
return ret;
}
}

rate = max(sum_bw, max_peak_bw);

do_div(rate, qn->buswidth);

if (qn->rate == rate)
return 0;

for (i = 0; i < qp->num_clks; i++) {
ret = clk_set_rate(qp->bus_clks[i].clk, rate);
if (ret) {
pr_err("%s clk_set_rate error: %d\n",
qp->bus_clks[i].id, ret);
return ret;
}
}

qn->rate = rate;

return 0;
}

int qnoc_probe(struct platform_device *pdev, size_t cd_size, int cd_num,
const struct clk_bulk_data *cd)
{
struct device *dev = &pdev->dev;
const struct qcom_icc_desc *desc;
struct icc_onecell_data *data;
struct icc_provider *provider;
struct qcom_icc_node **qnodes;
struct qcom_icc_provider *qp;
struct icc_node *node;
size_t num_nodes, i;
int ret;

/* wait for the RPM proxy */
if (!qcom_icc_rpm_smd_available())
return -EPROBE_DEFER;

desc = of_device_get_match_data(dev);
if (!desc)
return -EINVAL;

qnodes = desc->nodes;
num_nodes = desc->num_nodes;

qp = devm_kzalloc(dev, sizeof(*qp), GFP_KERNEL);
if (!qp)
return -ENOMEM;

data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes),
GFP_KERNEL);
if (!data)
return -ENOMEM;

qp->bus_clks = devm_kmemdup(dev, cd, cd_size,
GFP_KERNEL);
if (!qp->bus_clks)
return -ENOMEM;

qp->num_clks = cd_num;
ret = devm_clk_bulk_get(dev, qp->num_clks, qp->bus_clks);
if (ret)
return ret;

ret = clk_bulk_prepare_enable(qp->num_clks, qp->bus_clks);
if (ret)
return ret;

provider = &qp->provider;
INIT_LIST_HEAD(&provider->nodes);
provider->dev = dev;
provider->set = qcom_icc_set;
provider->aggregate = icc_std_aggregate;
provider->xlate = of_icc_xlate_onecell;
provider->data = data;

ret = icc_provider_add(provider);
if (ret) {
dev_err(dev, "error adding interconnect provider: %d\n", ret);
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
return ret;
}

for (i = 0; i < num_nodes; i++) {
size_t j;

node = icc_node_create(qnodes[i]->id);
if (IS_ERR(node)) {
ret = PTR_ERR(node);
goto err;
}

node->name = qnodes[i]->name;
node->data = qnodes[i];
icc_node_add(node, provider);

for (j = 0; j < qnodes[i]->num_links; j++)
icc_link_create(node, qnodes[i]->links[j]);

data->nodes[i] = node;
}
data->num_nodes = num_nodes;

platform_set_drvdata(pdev, qp);

return 0;
err:
icc_nodes_remove(provider);
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
icc_provider_del(provider);

return ret;
}
EXPORT_SYMBOL(qnoc_probe);

int qnoc_remove(struct platform_device *pdev)
{
struct qcom_icc_provider *qp = platform_get_drvdata(pdev);

icc_nodes_remove(&qp->provider);
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
return icc_provider_del(&qp->provider);
}
EXPORT_SYMBOL(qnoc_remove);
Loading

0 comments on commit 5157110

Please sign in to comment.