Skip to content

Commit 226e58b

Browse files
author
Georgi Djakov
committed
Merge branch 'icc-rpmh-qos' into icc-next
This series adds QoS support for QNOC type device which can be found on SC7280 platform. It adds support for programming priority, priority forward disable and urgency forwarding. This helps in priortizing the traffic originating from different interconnect masters at NOC (Network On Chip). * icc-rpmh-qos dt-bindings: interconnect: add clock property to enable QOS on SC7280 interconnect: qcom: icc-rpmh: Add QoS configuration support interconnect: qcom: sc7280: enable QoS configuration interconnect: qcom: Fix DT backwards compatibility for QoS Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Georgi Djakov <[email protected]>
2 parents 19990ff + 8b6bd83 commit 226e58b

File tree

4 files changed

+458
-0
lines changed

4 files changed

+458
-0
lines changed

Documentation/devicetree/bindings/interconnect/qcom,sc7280-rpmh.yaml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ properties:
3535
reg:
3636
maxItems: 1
3737

38+
clocks:
39+
minItems: 1
40+
maxItems: 2
41+
3842
required:
3943
- compatible
4044

@@ -53,10 +57,50 @@ allOf:
5357
required:
5458
- reg
5559

60+
- if:
61+
properties:
62+
compatible:
63+
contains:
64+
enum:
65+
- qcom,sc7280-aggre1-noc
66+
then:
67+
properties:
68+
clocks:
69+
items:
70+
- description: aggre UFS PHY AXI clock
71+
- description: aggre USB3 PRIM AXI clock
72+
73+
- if:
74+
properties:
75+
compatible:
76+
contains:
77+
enum:
78+
- qcom,sc7280-aggre2-noc
79+
then:
80+
properties:
81+
clocks:
82+
items:
83+
- description: RPMH CC IPA clock
84+
85+
- if:
86+
properties:
87+
compatible:
88+
contains:
89+
enum:
90+
- qcom,sc7280-aggre1-noc
91+
- qcom,sc7280-aggre2-noc
92+
then:
93+
required:
94+
- clocks
95+
else:
96+
properties:
97+
clocks: false
98+
5699
unevaluatedProperties: false
57100

58101
examples:
59102
- |
103+
#include <dt-bindings/clock/qcom,gcc-sc7280.h>
60104
interconnect {
61105
compatible = "qcom,sc7280-clk-virt";
62106
#interconnect-cells = <2>;
@@ -69,3 +113,12 @@ examples:
69113
#interconnect-cells = <2>;
70114
qcom,bcm-voters = <&apps_bcm_voter>;
71115
};
116+
117+
interconnect@16e0000 {
118+
reg = <0x016e0000 0x1c080>;
119+
compatible = "qcom,sc7280-aggre1-noc";
120+
#interconnect-cells = <2>;
121+
qcom,bcm-voters = <&apps_bcm_voter>;
122+
clocks = <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
123+
<&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>;
124+
};

drivers/interconnect/qcom/icc-rpmh.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
// SPDX-License-Identifier: GPL-2.0
22
/*
33
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
4+
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
45
*/
56

7+
#include <linux/bitfield.h>
8+
#include <linux/clk.h>
69
#include <linux/interconnect.h>
710
#include <linux/interconnect-provider.h>
811
#include <linux/module.h>
@@ -14,6 +17,38 @@
1417
#include "icc-common.h"
1518
#include "icc-rpmh.h"
1619

20+
/* QNOC QoS */
21+
#define QOSGEN_MAINCTL_LO(p, qp) (0x8 + (p->port_offsets[qp]))
22+
#define QOS_SLV_URG_MSG_EN_MASK GENMASK(3, 3)
23+
#define QOS_DFLT_PRIO_MASK GENMASK(6, 4)
24+
#define QOS_DISABLE_MASK GENMASK(24, 24)
25+
26+
/**
27+
* qcom_icc_set_qos - initialize static QoS configurations
28+
* @qp: qcom icc provider to which @node belongs
29+
* @node: qcom icc node to operate on
30+
*/
31+
static void qcom_icc_set_qos(struct qcom_icc_provider *qp,
32+
struct qcom_icc_node *node)
33+
{
34+
const struct qcom_icc_qosbox *qos = node->qosbox;
35+
int port;
36+
37+
for (port = 0; port < qos->num_ports; port++) {
38+
regmap_update_bits(qp->regmap, QOSGEN_MAINCTL_LO(qos, port),
39+
QOS_DISABLE_MASK,
40+
FIELD_PREP(QOS_DISABLE_MASK, qos->prio_fwd_disable));
41+
42+
regmap_update_bits(qp->regmap, QOSGEN_MAINCTL_LO(qos, port),
43+
QOS_DFLT_PRIO_MASK,
44+
FIELD_PREP(QOS_DFLT_PRIO_MASK, qos->prio));
45+
46+
regmap_update_bits(qp->regmap, QOSGEN_MAINCTL_LO(qos, port),
47+
QOS_SLV_URG_MSG_EN_MASK,
48+
FIELD_PREP(QOS_SLV_URG_MSG_EN_MASK, qos->urg_fwd));
49+
}
50+
}
51+
1752
/**
1853
* qcom_icc_pre_aggregate - cleans up stale values from prior icc_set
1954
* @node: icc node to operate on
@@ -159,6 +194,36 @@ int qcom_icc_bcm_init(struct qcom_icc_bcm *bcm, struct device *dev)
159194
}
160195
EXPORT_SYMBOL_GPL(qcom_icc_bcm_init);
161196

197+
/**
198+
* qcom_icc_rpmh_configure_qos - configure QoS parameters
199+
* @qp: qcom icc provider associated with QoS endpoint nodes
200+
*
201+
* Return: 0 on success, or an error code otherwise
202+
*/
203+
static int qcom_icc_rpmh_configure_qos(struct qcom_icc_provider *qp)
204+
{
205+
struct qcom_icc_node *qnode;
206+
size_t i;
207+
int ret;
208+
209+
ret = clk_bulk_prepare_enable(qp->num_clks, qp->clks);
210+
if (ret)
211+
return ret;
212+
213+
for (i = 0; i < qp->num_nodes; i++) {
214+
qnode = qp->nodes[i];
215+
if (!qnode)
216+
continue;
217+
218+
if (qnode->qosbox)
219+
qcom_icc_set_qos(qp, qnode);
220+
}
221+
222+
clk_bulk_disable_unprepare(qp->num_clks, qp->clks);
223+
224+
return ret;
225+
}
226+
162227
int qcom_icc_rpmh_probe(struct platform_device *pdev)
163228
{
164229
const struct qcom_icc_desc *desc;
@@ -199,7 +264,9 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
199264

200265
qp->dev = dev;
201266
qp->bcms = desc->bcms;
267+
qp->nodes = desc->nodes;
202268
qp->num_bcms = desc->num_bcms;
269+
qp->num_nodes = desc->num_nodes;
203270

204271
qp->voter = of_bcm_voter_get(qp->dev, NULL);
205272
if (IS_ERR(qp->voter))
@@ -229,6 +296,32 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
229296
data->nodes[i] = node;
230297
}
231298

299+
if (desc->config) {
300+
struct resource *res;
301+
void __iomem *base;
302+
303+
base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
304+
if (IS_ERR(base))
305+
goto skip_qos_config;
306+
307+
qp->regmap = devm_regmap_init_mmio(dev, base, desc->config);
308+
if (IS_ERR(qp->regmap)) {
309+
dev_info(dev, "Skipping QoS, regmap failed; %ld\n", PTR_ERR(qp->regmap));
310+
goto skip_qos_config;
311+
}
312+
313+
qp->num_clks = devm_clk_bulk_get_all(qp->dev, &qp->clks);
314+
if (qp->num_clks < 0 || (!qp->num_clks && desc->qos_clks_required)) {
315+
dev_info(dev, "Skipping QoS, failed to get clk: %d\n", qp->num_clks);
316+
goto skip_qos_config;
317+
}
318+
319+
ret = qcom_icc_rpmh_configure_qos(qp);
320+
if (ret)
321+
dev_info(dev, "Failed to program QoS: %d\n", ret);
322+
}
323+
324+
skip_qos_config:
232325
ret = icc_provider_register(provider);
233326
if (ret)
234327
goto err_remove_nodes;

drivers/interconnect/qcom/icc-rpmh.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22
/*
33
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
4+
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
45
*/
56

67
#ifndef __DRIVERS_INTERCONNECT_QCOM_ICC_RPMH_H__
78
#define __DRIVERS_INTERCONNECT_QCOM_ICC_RPMH_H__
89

910
#include <dt-bindings/interconnect/qcom,icc.h>
11+
#include <linux/regmap.h>
1012

1113
#define to_qcom_provider(_provider) \
1214
container_of(_provider, struct qcom_icc_provider, provider)
@@ -18,13 +20,23 @@
1820
* @bcms: list of bcms that maps to the provider
1921
* @num_bcms: number of @bcms
2022
* @voter: bcm voter targeted by this provider
23+
* @nodes: list of icc nodes that maps to the provider
24+
* @num_nodes: number of @nodes
25+
* @regmap: used for QoS, register access
26+
* @clks : clks required for register access
27+
* @num_clks: number of @clks
2128
*/
2229
struct qcom_icc_provider {
2330
struct icc_provider provider;
2431
struct device *dev;
2532
struct qcom_icc_bcm * const *bcms;
2633
size_t num_bcms;
2734
struct bcm_voter *voter;
35+
struct qcom_icc_node * const *nodes;
36+
size_t num_nodes;
37+
struct regmap *regmap;
38+
struct clk_bulk_data *clks;
39+
int num_clks;
2840
};
2941

3042
/**
@@ -41,6 +53,26 @@ struct bcm_db {
4153
u8 reserved;
4254
};
4355

56+
#define MAX_PORTS 2
57+
58+
/**
59+
* struct qcom_icc_qosbox - Qualcomm specific QoS config
60+
* @prio: priority value assigned to requests on the node
61+
* @urg_fwd: whether to forward the urgency promotion issued by master
62+
* (endpoint), or discard
63+
* @prio_fwd_disable: whether to forward the priority driven by master, or
64+
* override by @prio
65+
* @num_ports: number of @ports
66+
* @port_offsets: qos register offsets
67+
*/
68+
struct qcom_icc_qosbox {
69+
const u32 prio;
70+
const bool urg_fwd;
71+
const bool prio_fwd_disable;
72+
const u32 num_ports;
73+
const u32 port_offsets[MAX_PORTS];
74+
};
75+
4476
#define MAX_LINKS 128
4577
#define MAX_BCMS 64
4678
#define MAX_BCM_PER_NODE 3
@@ -58,6 +90,7 @@ struct bcm_db {
5890
* @max_peak: current max aggregate value of all peak bw requests
5991
* @bcms: list of bcms associated with this logical node
6092
* @num_bcms: num of @bcms
93+
* @qosbox: QoS config data associated with node
6194
*/
6295
struct qcom_icc_node {
6396
const char *name;
@@ -70,6 +103,7 @@ struct qcom_icc_node {
70103
u64 max_peak[QCOM_ICC_NUM_BUCKETS];
71104
struct qcom_icc_bcm *bcms[MAX_BCM_PER_NODE];
72105
size_t num_bcms;
106+
const struct qcom_icc_qosbox *qosbox;
73107
};
74108

75109
/**
@@ -114,10 +148,12 @@ struct qcom_icc_fabric {
114148
};
115149

116150
struct qcom_icc_desc {
151+
const struct regmap_config *config;
117152
struct qcom_icc_node * const *nodes;
118153
size_t num_nodes;
119154
struct qcom_icc_bcm * const *bcms;
120155
size_t num_bcms;
156+
bool qos_clks_required;
121157
};
122158

123159
int qcom_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,

0 commit comments

Comments
 (0)