Skip to content

Commit 0a7be6b

Browse files
Odelu KukatlaGeorgi Djakov
authored andcommitted
interconnect: qcom: icc-rpmh: Add QoS configuration support
Add QoS support for QNOC device for configuring priority, priority forward disable and urgency forwarding. QoS is required to prioritize the traffic originating from different interconnect masters at NoC (Network On Chip). Signed-off-by: Odelu Kukatla <[email protected]> Reviewed-by: Konrad Dybcio <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Georgi Djakov <[email protected]>
1 parent 6822b0c commit 0a7be6b

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed

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) {
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: 35 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,6 +148,7 @@ 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;

0 commit comments

Comments
 (0)