1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
6 #include <linux/interconnect.h>
7 #include <linux/interconnect-provider.h>
8 #include <linux/module.h>
10 #include "bcm-voter.h"
14 * qcom_icc_pre_aggregate - cleans up stale values from prior icc_set
15 * @node: icc node to operate on
17 void qcom_icc_pre_aggregate(struct icc_node
*node
)
20 struct qcom_icc_node
*qn
;
24 for (i
= 0; i
< QCOM_ICC_NUM_BUCKETS
; i
++) {
29 EXPORT_SYMBOL_GPL(qcom_icc_pre_aggregate
);
32 * qcom_icc_aggregate - aggregate bw for buckets indicated by tag
33 * @node: node to aggregate
34 * @tag: tag to indicate which buckets to aggregate
35 * @avg_bw: new bw to sum aggregate
36 * @peak_bw: new bw to max aggregate
37 * @agg_avg: existing aggregate avg bw val
38 * @agg_peak: existing aggregate peak bw val
40 int qcom_icc_aggregate(struct icc_node
*node
, u32 tag
, u32 avg_bw
,
41 u32 peak_bw
, u32
*agg_avg
, u32
*agg_peak
)
44 struct qcom_icc_node
*qn
;
45 struct qcom_icc_provider
*qp
;
48 qp
= to_qcom_provider(node
->provider
);
51 tag
= QCOM_ICC_TAG_ALWAYS
;
53 for (i
= 0; i
< QCOM_ICC_NUM_BUCKETS
; i
++) {
55 qn
->sum_avg
[i
] += avg_bw
;
56 qn
->max_peak
[i
] = max_t(u32
, qn
->max_peak
[i
], peak_bw
);
61 *agg_peak
= max_t(u32
, *agg_peak
, peak_bw
);
63 for (i
= 0; i
< qn
->num_bcms
; i
++)
64 qcom_icc_bcm_voter_add(qp
->voter
, qn
->bcms
[i
]);
68 EXPORT_SYMBOL_GPL(qcom_icc_aggregate
);
71 * qcom_icc_set - set the constraints based on path
72 * @src: source node for the path to set constraints on
73 * @dst: destination node for the path to set constraints on
75 * Return: 0 on success, or an error code otherwise
77 int qcom_icc_set(struct icc_node
*src
, struct icc_node
*dst
)
79 struct qcom_icc_provider
*qp
;
80 struct icc_node
*node
;
87 qp
= to_qcom_provider(node
->provider
);
89 qcom_icc_bcm_voter_commit(qp
->voter
);
93 EXPORT_SYMBOL_GPL(qcom_icc_set
);
96 * qcom_icc_bcm_init - populates bcm aux data and connect qnodes
97 * @bcm: bcm to be initialized
98 * @dev: associated provider device
100 * Return: 0 on success, or an error code otherwise
102 int qcom_icc_bcm_init(struct qcom_icc_bcm
*bcm
, struct device
*dev
)
104 struct qcom_icc_node
*qn
;
105 const struct bcm_db
*data
;
109 /* BCM is already initialised*/
113 bcm
->addr
= cmd_db_read_addr(bcm
->name
);
115 dev_err(dev
, "%s could not find RPMh address\n",
120 data
= cmd_db_read_aux_data(bcm
->name
, &data_count
);
122 dev_err(dev
, "%s command db read error (%ld)\n",
123 bcm
->name
, PTR_ERR(data
));
124 return PTR_ERR(data
);
127 dev_err(dev
, "%s command db missing or partial aux data\n",
132 bcm
->aux_data
.unit
= le32_to_cpu(data
->unit
);
133 bcm
->aux_data
.width
= le16_to_cpu(data
->width
);
134 bcm
->aux_data
.vcd
= data
->vcd
;
135 bcm
->aux_data
.reserved
= data
->reserved
;
136 INIT_LIST_HEAD(&bcm
->list
);
137 INIT_LIST_HEAD(&bcm
->ws_list
);
139 /* Link Qnodes to their respective BCMs */
140 for (i
= 0; i
< bcm
->num_nodes
; i
++) {
142 qn
->bcms
[qn
->num_bcms
] = bcm
;
148 EXPORT_SYMBOL_GPL(qcom_icc_bcm_init
);
150 MODULE_LICENSE("GPL v2");