Lines Matching +full:fixed +full:- +full:mmio +full:- +full:clock
1 // SPDX-License-Identifier: GPL-2.0
7 #include <linux/interconnect-provider.h>
16 #include "icc-common.h"
17 #include "icc-rpm.h"
55 struct icc_provider *provider = src->provider; in qcom_icc_set_qnoc_qos()
57 struct qcom_icc_node *qn = src->data; in qcom_icc_set_qnoc_qos()
58 struct qcom_icc_qos *qos = &qn->qos; in qcom_icc_set_qnoc_qos()
61 rc = regmap_update_bits(qp->regmap, in qcom_icc_set_qnoc_qos()
62 qp->qos_offset + QNOC_QOS_MCTL_LOWn_ADDR(qos->qos_port), in qcom_icc_set_qnoc_qos()
64 qos->areq_prio << QNOC_QOS_MCTL_DFLT_PRIO_SHIFT); in qcom_icc_set_qnoc_qos()
68 return regmap_update_bits(qp->regmap, in qcom_icc_set_qnoc_qos()
69 qp->qos_offset + QNOC_QOS_MCTL_LOWn_ADDR(qos->qos_port), in qcom_icc_set_qnoc_qos()
71 !!qos->urg_fwd_en << QNOC_QOS_MCTL_URGFWD_EN_SHIFT); in qcom_icc_set_qnoc_qos()
81 val = qos->prio_level; in qcom_icc_bimc_set_qos_health()
84 val |= qos->areq_prio << M_BKE_HEALTH_CFG_AREQPRIO_SHIFT; in qcom_icc_bimc_set_qos_health()
89 val |= qos->limit_commands << M_BKE_HEALTH_CFG_LIMITCMDS_SHIFT; in qcom_icc_bimc_set_qos_health()
93 return regmap_update_bits(qp->regmap, in qcom_icc_bimc_set_qos_health()
94 qp->qos_offset + M_BKE_HEALTH_CFG_ADDR(regnum, qos->qos_port), in qcom_icc_bimc_set_qos_health()
107 qn = src->data; in qcom_icc_set_bimc_qos()
108 provider = src->provider; in qcom_icc_set_bimc_qos()
111 if (qn->qos.qos_mode != NOC_QOS_MODE_INVALID) in qcom_icc_set_bimc_qos()
112 mode = qn->qos.qos_mode; in qcom_icc_set_bimc_qos()
118 for (i = 3; i >= 0; i--) { in qcom_icc_set_bimc_qos()
120 &qn->qos, i); in qcom_icc_set_bimc_qos()
125 /* Set BKE_EN to 1 when Fixed, Regulator or Limiter Mode */ in qcom_icc_set_bimc_qos()
129 return regmap_update_bits(qp->regmap, in qcom_icc_set_bimc_qos()
130 qp->qos_offset + M_BKE_EN_ADDR(qn->qos.qos_port), in qcom_icc_set_bimc_qos()
141 val = qos->areq_prio << NOC_QOS_PRIORITY_P1_SHIFT; in qcom_icc_noc_set_qos_priority()
142 rc = regmap_update_bits(qp->regmap, in qcom_icc_noc_set_qos_priority()
143 qp->qos_offset + NOC_QOS_PRIORITYn_ADDR(qos->qos_port), in qcom_icc_noc_set_qos_priority()
148 return regmap_update_bits(qp->regmap, in qcom_icc_noc_set_qos_priority()
149 qp->qos_offset + NOC_QOS_PRIORITYn_ADDR(qos->qos_port), in qcom_icc_noc_set_qos_priority()
150 NOC_QOS_PRIORITY_P0_MASK, qos->prio_level); in qcom_icc_noc_set_qos_priority()
161 qn = src->data; in qcom_icc_set_noc_qos()
162 provider = src->provider; in qcom_icc_set_noc_qos()
165 if (qn->qos.qos_port < 0) { in qcom_icc_set_noc_qos()
166 dev_dbg(src->provider->dev, in qcom_icc_set_noc_qos()
168 qn->name); in qcom_icc_set_noc_qos()
172 if (qn->qos.qos_mode == NOC_QOS_MODE_FIXED) { in qcom_icc_set_noc_qos()
173 dev_dbg(src->provider->dev, "NoC QoS: %s: Set Fixed mode\n", qn->name); in qcom_icc_set_noc_qos()
175 rc = qcom_icc_noc_set_qos_priority(qp, &qn->qos); in qcom_icc_set_noc_qos()
178 } else if (qn->qos.qos_mode == NOC_QOS_MODE_BYPASS) { in qcom_icc_set_noc_qos()
179 dev_dbg(src->provider->dev, "NoC QoS: %s: Set Bypass mode\n", qn->name); in qcom_icc_set_noc_qos()
185 return regmap_update_bits(qp->regmap, in qcom_icc_set_noc_qos()
186 qp->qos_offset + NOC_QOS_MODEn_ADDR(qn->qos.qos_port), in qcom_icc_set_noc_qos()
192 struct qcom_icc_provider *qp = to_qcom_provider(node->provider); in qcom_icc_qos_set()
193 struct qcom_icc_node *qn = node->data; in qcom_icc_qos_set()
195 dev_dbg(node->provider->dev, "Setting QoS for %s\n", qn->name); in qcom_icc_qos_set()
197 switch (qp->type) { in qcom_icc_qos_set()
212 if (qn->qos.ap_owned) in qcom_icc_rpm_set()
218 if (qn->mas_rpm_id != -1) { in qcom_icc_rpm_set()
221 qn->mas_rpm_id, in qcom_icc_rpm_set()
225 qn->mas_rpm_id, ret); in qcom_icc_rpm_set()
230 if (qn->slv_rpm_id != -1) { in qcom_icc_rpm_set()
233 qn->slv_rpm_id, in qcom_icc_rpm_set()
237 qn->slv_rpm_id, ret); in qcom_icc_rpm_set()
247 * qcom_icc_pre_bw_aggregate - cleans up values before re-aggregate requests
255 qn = node->data; in qcom_icc_pre_bw_aggregate()
257 qn->sum_avg[i] = 0; in qcom_icc_pre_bw_aggregate()
258 qn->max_peak[i] = 0; in qcom_icc_pre_bw_aggregate()
263 * qcom_icc_bw_aggregate - aggregate bw for buckets indicated by tag
277 qn = node->data; in qcom_icc_bw_aggregate()
284 qn->sum_avg[i] += avg_bw; in qcom_icc_bw_aggregate()
285 qn->max_peak[i] = max_t(u32, qn->max_peak[i], peak_bw); in qcom_icc_bw_aggregate()
295 * qcom_icc_bus_aggregate - calculate bus clock rates by traversing all nodes
297 * @agg_clk_rate: array containing the aggregated clock rates in kHz
308 * every bucket and convert them into bus clock rates. in qcom_icc_bus_aggregate()
310 list_for_each_entry(node, &provider->nodes, node_list) { in qcom_icc_bus_aggregate()
311 qn = node->data; in qcom_icc_bus_aggregate()
313 if (qn->channels) in qcom_icc_bus_aggregate()
314 agg_avg_rate = div_u64(qn->sum_avg[i], qn->channels); in qcom_icc_bus_aggregate()
316 agg_avg_rate = qn->sum_avg[i]; in qcom_icc_bus_aggregate()
318 agg_rate = max_t(u64, agg_avg_rate, qn->max_peak[i]); in qcom_icc_bus_aggregate()
319 do_div(agg_rate, qn->buswidth); in qcom_icc_bus_aggregate()
335 src_qn = src->data; in qcom_icc_set()
337 dst_qn = dst->data; in qcom_icc_set()
338 provider = src->provider; in qcom_icc_set()
345 ret = qcom_icc_rpm_set(src_qn, src_qn->sum_avg); in qcom_icc_set()
350 ret = qcom_icc_rpm_set(dst_qn, dst_qn->sum_avg); in qcom_icc_set()
355 /* Some providers don't have a bus clock to scale */ in qcom_icc_set()
356 if (!qp->bus_clk_desc && !qp->bus_clk) in qcom_icc_set()
363 if (qp->keep_alive) in qcom_icc_set()
366 /* Some providers have a non-RPM-owned bus clock - convert kHz->Hz for the CCF */ in qcom_icc_set()
367 if (qp->bus_clk) { in qcom_icc_set()
371 return clk_set_rate(qp->bus_clk, active_rate); in qcom_icc_set()
378 if (active_rate != qp->bus_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE]) { in qcom_icc_set()
379 ret = qcom_icc_rpm_set_bus_rate(qp->bus_clk_desc, QCOM_SMD_RPM_ACTIVE_STATE, in qcom_icc_set()
385 qp->bus_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE] = active_rate; in qcom_icc_set()
388 if (sleep_rate != qp->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE]) { in qcom_icc_set()
389 ret = qcom_icc_rpm_set_bus_rate(qp->bus_clk_desc, QCOM_SMD_RPM_SLEEP_STATE, in qcom_icc_set()
395 qp->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE] = sleep_rate; in qcom_icc_set()
403 struct device *dev = &pdev->dev; in qnoc_probe()
417 return -EPROBE_DEFER; in qnoc_probe()
421 return -EINVAL; in qnoc_probe()
423 qnodes = desc->nodes; in qnoc_probe()
424 num_nodes = desc->num_nodes; in qnoc_probe()
426 if (desc->num_intf_clocks) { in qnoc_probe()
427 cds = desc->intf_clocks; in qnoc_probe()
428 cd_num = desc->num_intf_clocks; in qnoc_probe()
436 return -ENOMEM; in qnoc_probe()
438 qp->intf_clks = devm_kcalloc(dev, cd_num, sizeof(*qp->intf_clks), GFP_KERNEL); in qnoc_probe()
439 if (!qp->intf_clks) in qnoc_probe()
440 return -ENOMEM; in qnoc_probe()
442 if (desc->bus_clk_desc) { in qnoc_probe()
443 qp->bus_clk_desc = devm_kzalloc(dev, sizeof(*qp->bus_clk_desc), in qnoc_probe()
445 if (!qp->bus_clk_desc) in qnoc_probe()
446 return -ENOMEM; in qnoc_probe()
448 qp->bus_clk_desc = desc->bus_clk_desc; in qnoc_probe()
450 /* Some older SoCs may have a single non-RPM-owned bus clock. */ in qnoc_probe()
451 qp->bus_clk = devm_clk_get_optional(dev, "bus"); in qnoc_probe()
452 if (IS_ERR(qp->bus_clk)) in qnoc_probe()
453 return PTR_ERR(qp->bus_clk); in qnoc_probe()
459 return -ENOMEM; in qnoc_probe()
461 qp->num_intf_clks = cd_num; in qnoc_probe()
463 qp->intf_clks[i].id = cds[i]; in qnoc_probe()
465 qp->keep_alive = desc->keep_alive; in qnoc_probe()
466 qp->type = desc->type; in qnoc_probe()
467 qp->qos_offset = desc->qos_offset; in qnoc_probe()
469 if (desc->regmap_cfg) { in qnoc_probe()
471 void __iomem *mmio; in qnoc_probe() local
476 qp->regmap = dev_get_regmap(dev->parent, NULL); in qnoc_probe()
477 if (qp->regmap) in qnoc_probe()
479 return -ENODEV; in qnoc_probe()
482 mmio = devm_ioremap_resource(dev, res); in qnoc_probe()
483 if (IS_ERR(mmio)) in qnoc_probe()
484 return PTR_ERR(mmio); in qnoc_probe()
486 qp->regmap = devm_regmap_init_mmio(dev, mmio, desc->regmap_cfg); in qnoc_probe()
487 if (IS_ERR(qp->regmap)) { in qnoc_probe()
489 return PTR_ERR(qp->regmap); in qnoc_probe()
494 ret = clk_prepare_enable(qp->bus_clk); in qnoc_probe()
498 ret = devm_clk_bulk_get(dev, qp->num_intf_clks, qp->intf_clks); in qnoc_probe()
502 provider = &qp->provider; in qnoc_probe()
503 provider->dev = dev; in qnoc_probe()
504 provider->set = qcom_icc_set; in qnoc_probe()
505 provider->pre_aggregate = qcom_icc_pre_bw_aggregate; in qnoc_probe()
506 provider->aggregate = qcom_icc_bw_aggregate; in qnoc_probe()
507 provider->xlate_extended = qcom_icc_xlate_extended; in qnoc_probe()
508 provider->data = data; in qnoc_probe()
513 ret = clk_bulk_prepare_enable(qp->num_intf_clks, qp->intf_clks); in qnoc_probe()
520 node = icc_node_create(qnodes[i]->id); in qnoc_probe()
522 clk_bulk_disable_unprepare(qp->num_intf_clks, in qnoc_probe()
523 qp->intf_clks); in qnoc_probe()
528 node->name = qnodes[i]->name; in qnoc_probe()
529 node->data = qnodes[i]; in qnoc_probe()
532 for (j = 0; j < qnodes[i]->num_links; j++) in qnoc_probe()
533 icc_link_create(node, qnodes[i]->links[j]); in qnoc_probe()
536 if (qnodes[i]->qos.ap_owned && in qnoc_probe()
537 qnodes[i]->qos.qos_mode != NOC_QOS_MODE_INVALID) { in qnoc_probe()
540 clk_bulk_disable_unprepare(qp->num_intf_clks, in qnoc_probe()
541 qp->intf_clks); in qnoc_probe()
546 data->nodes[i] = node; in qnoc_probe()
548 data->num_nodes = num_nodes; in qnoc_probe()
550 clk_bulk_disable_unprepare(qp->num_intf_clks, qp->intf_clks); in qnoc_probe()
559 if (of_get_child_count(dev->of_node) > 0) { in qnoc_probe()
560 ret = of_platform_populate(dev->of_node, NULL, NULL, dev); in qnoc_probe()
572 clk_disable_unprepare(qp->bus_clk); in qnoc_probe()
582 icc_provider_deregister(&qp->provider); in qnoc_remove()
583 icc_nodes_remove(&qp->provider); in qnoc_remove()
584 clk_disable_unprepare(qp->bus_clk); in qnoc_remove()