Skip to content

Commit 0481107

Browse files
author
Georgi Djakov
committed
Merge branch 'icc-qcom-coefficients' into icc-next
Certain platforms require that some buses (or individual nodes) make some additional changes to the clock rate formula, throwing in some magic, Qualcomm-defined coefficients, to account for "inefficiencies". Add the framework for it and utilize it on a couple SoCs. * icc-qcom-coefficients interconnect: qcom: icc-rpm: Add AB/IB calculations coefficients interconnect: qcom: icc-rpm: Separate out clock rate calulcations interconnect: qcom: icc-rpm: Let nodes drive their own bus clock interconnect: qcom: icc-rpm: Check for node-specific rate coefficients interconnect: qcom: qcm2290: Hook up MAS_APPS_PROC's bus clock interconnecga qcom: qcm2290: Set AB coefficients interconnecgg acom: qcm2290: Update EBI channel configuration interconnect: qcom: sdm660: Set AB/IB coefficients interconnect: qcom: msm8996: Set AB/IB coefficients Link: https://lore.kernel.org/r/20230726-topic-icc_coeff-v4-0-c04b60caa467@linaro.org Signed-off-by: Georgi Djakov <djakov@kernel.org>
2 parents 0bb80ec + 1255f23 commit 0481107

6 files changed

Lines changed: 103 additions & 15 deletions

File tree

drivers/interconnect/qcom/icc-rpm-clocks.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ const struct rpm_clk_resource bimc_clk = {
2525
};
2626
EXPORT_SYMBOL_GPL(bimc_clk);
2727

28+
const struct rpm_clk_resource mem_1_clk = {
29+
.resource_type = QCOM_SMD_RPM_MEM_CLK,
30+
.clock_id = 1,
31+
};
32+
EXPORT_SYMBOL_GPL(mem_1_clk);
33+
2834
const struct rpm_clk_resource bus_0_clk = {
2935
.resource_type = QCOM_SMD_RPM_BUS_CLK,
3036
.clock_id = 0,

drivers/interconnect/qcom/icc-rpm.c

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -291,34 +291,53 @@ static int qcom_icc_bw_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
291291
return 0;
292292
}
293293

294+
static u64 qcom_icc_calc_rate(struct qcom_icc_provider *qp, struct qcom_icc_node *qn, int ctx)
295+
{
296+
u64 agg_avg_rate, agg_peak_rate, agg_rate;
297+
298+
if (qn->channels)
299+
agg_avg_rate = div_u64(qn->sum_avg[ctx], qn->channels);
300+
else
301+
agg_avg_rate = qn->sum_avg[ctx];
302+
303+
if (qn->ab_coeff) {
304+
agg_avg_rate = agg_avg_rate * qn->ab_coeff;
305+
agg_avg_rate = div_u64(agg_avg_rate, 100);
306+
}
307+
308+
if (qn->ib_coeff) {
309+
agg_peak_rate = qn->max_peak[ctx] * 100;
310+
agg_peak_rate = div_u64(qn->max_peak[ctx], qn->ib_coeff);
311+
} else {
312+
agg_peak_rate = qn->max_peak[ctx];
313+
}
314+
315+
agg_rate = max_t(u64, agg_avg_rate, agg_peak_rate);
316+
317+
return div_u64(agg_rate, qn->buswidth);
318+
}
319+
294320
/**
295321
* qcom_icc_bus_aggregate - calculate bus clock rates by traversing all nodes
296322
* @provider: generic interconnect provider
297323
* @agg_clk_rate: array containing the aggregated clock rates in kHz
298324
*/
299325
static void qcom_icc_bus_aggregate(struct icc_provider *provider, u64 *agg_clk_rate)
300326
{
301-
u64 agg_avg_rate, agg_rate;
327+
struct qcom_icc_provider *qp = to_qcom_provider(provider);
302328
struct qcom_icc_node *qn;
303329
struct icc_node *node;
304-
int i;
330+
int ctx;
305331

306332
/*
307333
* Iterate nodes on the provider, aggregate bandwidth requests for
308334
* every bucket and convert them into bus clock rates.
309335
*/
310336
list_for_each_entry(node, &provider->nodes, node_list) {
311337
qn = node->data;
312-
for (i = 0; i < QCOM_SMD_RPM_STATE_NUM; i++) {
313-
if (qn->channels)
314-
agg_avg_rate = div_u64(qn->sum_avg[i], qn->channels);
315-
else
316-
agg_avg_rate = qn->sum_avg[i];
317-
318-
agg_rate = max_t(u64, agg_avg_rate, qn->max_peak[i]);
319-
do_div(agg_rate, qn->buswidth);
320-
321-
agg_clk_rate[i] = max_t(u64, agg_clk_rate[i], agg_rate);
338+
for (ctx = 0; ctx < QCOM_SMD_RPM_STATE_NUM; ctx++) {
339+
agg_clk_rate[ctx] = max_t(u64, agg_clk_rate[ctx],
340+
qcom_icc_calc_rate(qp, qn, ctx));
322341
}
323342
}
324343
}
@@ -395,6 +414,33 @@ static int qcom_icc_set(struct icc_node *src, struct icc_node *dst)
395414
qp->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE] = sleep_rate;
396415
}
397416

417+
/* Handle the node-specific clock */
418+
if (!src_qn->bus_clk_desc)
419+
return 0;
420+
421+
active_rate = qcom_icc_calc_rate(qp, src_qn, QCOM_SMD_RPM_ACTIVE_STATE);
422+
sleep_rate = qcom_icc_calc_rate(qp, src_qn, QCOM_SMD_RPM_SLEEP_STATE);
423+
424+
if (active_rate != src_qn->bus_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE]) {
425+
ret = qcom_icc_rpm_set_bus_rate(src_qn->bus_clk_desc, QCOM_SMD_RPM_ACTIVE_STATE,
426+
active_rate);
427+
if (ret)
428+
return ret;
429+
430+
/* Cache the rate after we've successfully committed it to RPM */
431+
src_qn->bus_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE] = active_rate;
432+
}
433+
434+
if (sleep_rate != src_qn->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE]) {
435+
ret = qcom_icc_rpm_set_bus_rate(src_qn->bus_clk_desc, QCOM_SMD_RPM_SLEEP_STATE,
436+
sleep_rate);
437+
if (ret)
438+
return ret;
439+
440+
/* Cache the rate after we've successfully committed it to RPM */
441+
src_qn->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE] = sleep_rate;
442+
}
443+
398444
return 0;
399445
}
400446

@@ -517,6 +563,12 @@ int qnoc_probe(struct platform_device *pdev)
517563
for (i = 0; i < num_nodes; i++) {
518564
size_t j;
519565

566+
if (!qnodes[i]->ab_coeff)
567+
qnodes[i]->ab_coeff = qp->ab_coeff;
568+
569+
if (!qnodes[i]->ib_coeff)
570+
qnodes[i]->ib_coeff = qp->ib_coeff;
571+
520572
node = icc_node_create(qnodes[i]->id);
521573
if (IS_ERR(node)) {
522574
ret = PTR_ERR(node);

drivers/interconnect/qcom/icc-rpm.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ struct rpm_clk_resource {
4444
* @type: the ICC provider type
4545
* @regmap: regmap for QoS registers read/write access
4646
* @qos_offset: offset to QoS registers
47+
* @ab_coeff: a percentage-based coefficient for compensating the AB calculations
48+
* @ib_coeff: an inverse-percentage-based coefficient for compensating the IB calculations
4749
* @bus_clk_rate: bus clock rate in Hz
4850
* @bus_clk_desc: a pointer to a rpm_clk_resource description of bus clocks
4951
* @bus_clk: a pointer to a HLOS-owned bus clock
@@ -57,6 +59,8 @@ struct qcom_icc_provider {
5759
enum qcom_icc_type type;
5860
struct regmap *regmap;
5961
unsigned int qos_offset;
62+
u16 ab_coeff;
63+
u16 ib_coeff;
6064
u32 bus_clk_rate[QCOM_SMD_RPM_STATE_NUM];
6165
const struct rpm_clk_resource *bus_clk_desc;
6266
struct clk *bus_clk;
@@ -93,11 +97,15 @@ struct qcom_icc_qos {
9397
* @num_links: the total number of @links
9498
* @channels: number of channels at this node (e.g. DDR channels)
9599
* @buswidth: width of the interconnect between a node and the bus (bytes)
100+
* @bus_clk_desc: a pointer to a rpm_clk_resource description of bus clocks
96101
* @sum_avg: current sum aggregate value of all avg bw requests
97102
* @max_peak: current max aggregate value of all peak bw requests
98103
* @mas_rpm_id: RPM id for devices that are bus masters
99104
* @slv_rpm_id: RPM id for devices that are bus slaves
100105
* @qos: NoC QoS setting parameters
106+
* @ab_coeff: a percentage-based coefficient for compensating the AB calculations
107+
* @ib_coeff: an inverse-percentage-based coefficient for compensating the IB calculations
108+
* @bus_clk_rate: a pointer to an array containing bus clock rates in Hz
101109
*/
102110
struct qcom_icc_node {
103111
unsigned char *name;
@@ -106,11 +114,15 @@ struct qcom_icc_node {
106114
u16 num_links;
107115
u16 channels;
108116
u16 buswidth;
117+
const struct rpm_clk_resource *bus_clk_desc;
109118
u64 sum_avg[QCOM_SMD_RPM_STATE_NUM];
110119
u64 max_peak[QCOM_SMD_RPM_STATE_NUM];
111120
int mas_rpm_id;
112121
int slv_rpm_id;
113122
struct qcom_icc_qos qos;
123+
u16 ab_coeff;
124+
u16 ib_coeff;
125+
u32 bus_clk_rate[QCOM_SMD_RPM_STATE_NUM];
114126
};
115127

116128
struct qcom_icc_desc {
@@ -123,6 +135,8 @@ struct qcom_icc_desc {
123135
enum qcom_icc_type type;
124136
const struct regmap_config *regmap_cfg;
125137
unsigned int qos_offset;
138+
u16 ab_coeff;
139+
u16 ib_coeff;
126140
};
127141

128142
/* Valid for all bus types */
@@ -138,6 +152,7 @@ extern const struct rpm_clk_resource bimc_clk;
138152
extern const struct rpm_clk_resource bus_0_clk;
139153
extern const struct rpm_clk_resource bus_1_clk;
140154
extern const struct rpm_clk_resource bus_2_clk;
155+
extern const struct rpm_clk_resource mem_1_clk;
141156
extern const struct rpm_clk_resource mmaxi_0_clk;
142157
extern const struct rpm_clk_resource mmaxi_1_clk;
143158
extern const struct rpm_clk_resource qup_clk;

drivers/interconnect/qcom/msm8996.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ static struct qcom_icc_node mas_mdp_p0 = {
448448
.name = "mas_mdp_p0",
449449
.id = MSM8996_MASTER_MDP_PORT0,
450450
.buswidth = 32,
451+
.ib_coeff = 25,
451452
.mas_rpm_id = 8,
452453
.slv_rpm_id = -1,
453454
.qos.ap_owned = true,
@@ -463,6 +464,7 @@ static struct qcom_icc_node mas_mdp_p1 = {
463464
.name = "mas_mdp_p1",
464465
.id = MSM8996_MASTER_MDP_PORT1,
465466
.buswidth = 32,
467+
.ib_coeff = 25,
466468
.mas_rpm_id = 61,
467469
.slv_rpm_id = -1,
468470
.qos.ap_owned = true,
@@ -1889,7 +1891,8 @@ static const struct qcom_icc_desc msm8996_bimc = {
18891891
.nodes = bimc_nodes,
18901892
.num_nodes = ARRAY_SIZE(bimc_nodes),
18911893
.bus_clk_desc = &bimc_clk,
1892-
.regmap_cfg = &msm8996_bimc_regmap_config
1894+
.regmap_cfg = &msm8996_bimc_regmap_config,
1895+
.ab_coeff = 154,
18931896
};
18941897

18951898
static struct qcom_icc_node * const cnoc_nodes[] = {
@@ -2004,7 +2007,8 @@ static const struct qcom_icc_desc msm8996_mnoc = {
20042007
.bus_clk_desc = &mmaxi_0_clk,
20052008
.intf_clocks = mm_intf_clocks,
20062009
.num_intf_clocks = ARRAY_SIZE(mm_intf_clocks),
2007-
.regmap_cfg = &msm8996_mnoc_regmap_config
2010+
.regmap_cfg = &msm8996_mnoc_regmap_config,
2011+
.ab_coeff = 154,
20082012
};
20092013

20102014
static struct qcom_icc_node * const pnoc_nodes[] = {

drivers/interconnect/qcom/qcm2290.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ static struct qcom_icc_node mas_appss_proc = {
112112
.qos.qos_mode = NOC_QOS_MODE_FIXED,
113113
.qos.prio_level = 0,
114114
.qos.areq_prio = 0,
115+
.bus_clk_desc = &mem_1_clk,
116+
.ab_coeff = 159,
117+
.ib_coeff = 96,
115118
.mas_rpm_id = 0,
116119
.slv_rpm_id = -1,
117120
.num_links = ARRAY_SIZE(mas_appss_proc_links),
@@ -675,7 +678,8 @@ static struct qcom_icc_node mas_gfx3d = {
675678
static struct qcom_icc_node slv_ebi1 = {
676679
.name = "slv_ebi1",
677680
.id = QCM2290_SLAVE_EBI1,
678-
.buswidth = 8,
681+
.buswidth = 4,
682+
.channels = 2,
679683
.mas_rpm_id = -1,
680684
.slv_rpm_id = 0,
681685
};
@@ -1199,6 +1203,7 @@ static const struct qcom_icc_desc qcm2290_bimc = {
11991203
.keep_alive = true,
12001204
/* M_REG_BASE() in vendor msm_bus_bimc_adhoc driver */
12011205
.qos_offset = 0x8000,
1206+
.ab_coeff = 153,
12021207
};
12031208

12041209
static struct qcom_icc_node * const qcm2290_cnoc_nodes[] = {
@@ -1329,6 +1334,7 @@ static const struct qcom_icc_desc qcm2290_mmnrt_virt = {
13291334
.regmap_cfg = &qcm2290_snoc_regmap_config,
13301335
.keep_alive = true,
13311336
.qos_offset = 0x15000,
1337+
.ab_coeff = 142,
13321338
};
13331339

13341340
static struct qcom_icc_node * const qcm2290_mmrt_virt_nodes[] = {
@@ -1345,6 +1351,7 @@ static const struct qcom_icc_desc qcm2290_mmrt_virt = {
13451351
.regmap_cfg = &qcm2290_snoc_regmap_config,
13461352
.keep_alive = true,
13471353
.qos_offset = 0x15000,
1354+
.ab_coeff = 139,
13481355
};
13491356

13501357
static const struct of_device_id qcm2290_noc_of_match[] = {

drivers/interconnect/qcom/sdm660.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ static struct qcom_icc_node mas_mdp_p0 = {
602602
.name = "mas_mdp_p0",
603603
.id = SDM660_MASTER_MDP_P0,
604604
.buswidth = 16,
605+
.ib_coeff = 50,
605606
.mas_rpm_id = 8,
606607
.slv_rpm_id = -1,
607608
.qos.ap_owned = true,
@@ -621,6 +622,7 @@ static struct qcom_icc_node mas_mdp_p1 = {
621622
.name = "mas_mdp_p1",
622623
.id = SDM660_MASTER_MDP_P1,
623624
.buswidth = 16,
625+
.ib_coeff = 50,
624626
.mas_rpm_id = 61,
625627
.slv_rpm_id = -1,
626628
.qos.ap_owned = true,
@@ -1540,6 +1542,7 @@ static const struct qcom_icc_desc sdm660_bimc = {
15401542
.num_nodes = ARRAY_SIZE(sdm660_bimc_nodes),
15411543
.bus_clk_desc = &bimc_clk,
15421544
.regmap_cfg = &sdm660_bimc_regmap_config,
1545+
.ab_coeff = 153,
15431546
};
15441547

15451548
static struct qcom_icc_node * const sdm660_cnoc_nodes[] = {
@@ -1659,6 +1662,7 @@ static const struct qcom_icc_desc sdm660_mnoc = {
16591662
.intf_clocks = mm_intf_clocks,
16601663
.num_intf_clocks = ARRAY_SIZE(mm_intf_clocks),
16611664
.regmap_cfg = &sdm660_mnoc_regmap_config,
1665+
.ab_coeff = 153,
16621666
};
16631667

16641668
static struct qcom_icc_node * const sdm660_snoc_nodes[] = {

0 commit comments

Comments
 (0)