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()
298 if (qn->channels) in qcom_icc_calc_rate()
299 agg_avg_rate = div_u64(qn->sum_avg[ctx], qn->channels); in qcom_icc_calc_rate()
301 agg_avg_rate = qn->sum_avg[ctx]; in qcom_icc_calc_rate()
303 if (qn->ab_coeff) { in qcom_icc_calc_rate()
304 agg_avg_rate = agg_avg_rate * qn->ab_coeff; in qcom_icc_calc_rate()
308 if (qn->ib_coeff) { in qcom_icc_calc_rate()
309 agg_peak_rate = qn->max_peak[ctx] * 100; in qcom_icc_calc_rate()
310 agg_peak_rate = div_u64(agg_peak_rate, qn->ib_coeff); in qcom_icc_calc_rate()
312 agg_peak_rate = qn->max_peak[ctx]; in qcom_icc_calc_rate()
317 return div_u64(agg_rate, qn->buswidth); in qcom_icc_calc_rate()
321 * qcom_icc_bus_aggregate - calculate bus clock rates by traversing all nodes
323 * @agg_clk_rate: array containing the aggregated clock rates in kHz
334 * every bucket and convert them into bus clock rates. in qcom_icc_bus_aggregate()
336 list_for_each_entry(node, &provider->nodes, node_list) { in qcom_icc_bus_aggregate()
337 qn = node->data; in qcom_icc_bus_aggregate()
354 src_qn = src->data; in qcom_icc_set()
356 dst_qn = dst->data; in qcom_icc_set()
357 provider = src->provider; in qcom_icc_set()
364 ret = qcom_icc_rpm_set(src_qn, src_qn->sum_avg); in qcom_icc_set()
369 ret = qcom_icc_rpm_set(dst_qn, dst_qn->sum_avg); in qcom_icc_set()
374 /* Some providers don't have a bus clock to scale */ in qcom_icc_set()
375 if (!qp->bus_clk_desc && !qp->bus_clk) in qcom_icc_set()
382 if (qp->keep_alive) in qcom_icc_set()
385 /* Some providers have a non-RPM-owned bus clock - convert kHz->Hz for the CCF */ in qcom_icc_set()
386 if (qp->bus_clk) { in qcom_icc_set()
390 return clk_set_rate(qp->bus_clk, active_rate); in qcom_icc_set()
397 if (active_rate != qp->bus_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE]) { in qcom_icc_set()
398 ret = qcom_icc_rpm_set_bus_rate(qp->bus_clk_desc, QCOM_SMD_RPM_ACTIVE_STATE, in qcom_icc_set()
404 qp->bus_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE] = active_rate; in qcom_icc_set()
407 if (sleep_rate != qp->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE]) { in qcom_icc_set()
408 ret = qcom_icc_rpm_set_bus_rate(qp->bus_clk_desc, QCOM_SMD_RPM_SLEEP_STATE, in qcom_icc_set()
414 qp->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE] = sleep_rate; in qcom_icc_set()
417 /* Handle the node-specific clock */ in qcom_icc_set()
418 if (!src_qn->bus_clk_desc) in qcom_icc_set()
424 if (active_rate != src_qn->bus_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE]) { in qcom_icc_set()
425 ret = qcom_icc_rpm_set_bus_rate(src_qn->bus_clk_desc, QCOM_SMD_RPM_ACTIVE_STATE, in qcom_icc_set()
431 src_qn->bus_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE] = active_rate; in qcom_icc_set()
434 if (sleep_rate != src_qn->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE]) { in qcom_icc_set()
435 ret = qcom_icc_rpm_set_bus_rate(src_qn->bus_clk_desc, QCOM_SMD_RPM_SLEEP_STATE, in qcom_icc_set()
441 src_qn->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE] = sleep_rate; in qcom_icc_set()
449 struct device *dev = &pdev->dev; in qnoc_probe()
463 return -EPROBE_DEFER; in qnoc_probe()
467 return -EINVAL; in qnoc_probe()
469 qnodes = desc->nodes; in qnoc_probe()
470 num_nodes = desc->num_nodes; in qnoc_probe()
472 if (desc->num_intf_clocks) { in qnoc_probe()
473 cds = desc->intf_clocks; in qnoc_probe()
474 cd_num = desc->num_intf_clocks; in qnoc_probe()
482 return -ENOMEM; in qnoc_probe()
484 qp->intf_clks = devm_kcalloc(dev, cd_num, sizeof(*qp->intf_clks), GFP_KERNEL); in qnoc_probe()
485 if (!qp->intf_clks) in qnoc_probe()
486 return -ENOMEM; in qnoc_probe()
488 if (desc->bus_clk_desc) { in qnoc_probe()
489 qp->bus_clk_desc = devm_kzalloc(dev, sizeof(*qp->bus_clk_desc), in qnoc_probe()
491 if (!qp->bus_clk_desc) in qnoc_probe()
492 return -ENOMEM; in qnoc_probe()
494 qp->bus_clk_desc = desc->bus_clk_desc; in qnoc_probe()
496 /* Some older SoCs may have a single non-RPM-owned bus clock. */ in qnoc_probe()
497 qp->bus_clk = devm_clk_get_optional(dev, "bus"); in qnoc_probe()
498 if (IS_ERR(qp->bus_clk)) in qnoc_probe()
499 return PTR_ERR(qp->bus_clk); in qnoc_probe()
505 return -ENOMEM; in qnoc_probe()
507 qp->num_intf_clks = cd_num; in qnoc_probe()
509 qp->intf_clks[i].id = cds[i]; in qnoc_probe()
511 qp->keep_alive = desc->keep_alive; in qnoc_probe()
512 qp->type = desc->type; in qnoc_probe()
513 qp->qos_offset = desc->qos_offset; in qnoc_probe()
515 if (desc->regmap_cfg) { in qnoc_probe()
517 void __iomem *mmio; in qnoc_probe() local
522 qp->regmap = dev_get_regmap(dev->parent, NULL); in qnoc_probe()
523 if (qp->regmap) in qnoc_probe()
525 return -ENODEV; in qnoc_probe()
528 mmio = devm_ioremap_resource(dev, res); in qnoc_probe()
529 if (IS_ERR(mmio)) in qnoc_probe()
530 return PTR_ERR(mmio); in qnoc_probe()
532 qp->regmap = devm_regmap_init_mmio(dev, mmio, desc->regmap_cfg); in qnoc_probe()
533 if (IS_ERR(qp->regmap)) { in qnoc_probe()
535 return PTR_ERR(qp->regmap); in qnoc_probe()
540 ret = clk_prepare_enable(qp->bus_clk); in qnoc_probe()
544 ret = devm_clk_bulk_get(dev, qp->num_intf_clks, qp->intf_clks); in qnoc_probe()
548 provider = &qp->provider; in qnoc_probe()
549 provider->dev = dev; in qnoc_probe()
550 provider->set = qcom_icc_set; in qnoc_probe()
551 provider->pre_aggregate = qcom_icc_pre_bw_aggregate; in qnoc_probe()
552 provider->aggregate = qcom_icc_bw_aggregate; in qnoc_probe()
553 provider->xlate_extended = qcom_icc_xlate_extended; in qnoc_probe()
554 provider->data = data; in qnoc_probe()
559 ret = clk_bulk_prepare_enable(qp->num_intf_clks, qp->intf_clks); in qnoc_probe()
566 if (!qnodes[i]->ab_coeff) in qnoc_probe()
567 qnodes[i]->ab_coeff = qp->ab_coeff; in qnoc_probe()
569 if (!qnodes[i]->ib_coeff) in qnoc_probe()
570 qnodes[i]->ib_coeff = qp->ib_coeff; in qnoc_probe()
572 node = icc_node_create(qnodes[i]->id); in qnoc_probe()
574 clk_bulk_disable_unprepare(qp->num_intf_clks, in qnoc_probe()
575 qp->intf_clks); in qnoc_probe()
580 node->name = qnodes[i]->name; in qnoc_probe()
581 node->data = qnodes[i]; in qnoc_probe()
584 for (j = 0; j < qnodes[i]->num_links; j++) in qnoc_probe()
585 icc_link_create(node, qnodes[i]->links[j]); in qnoc_probe()
588 if (qnodes[i]->qos.ap_owned && in qnoc_probe()
589 qnodes[i]->qos.qos_mode != NOC_QOS_MODE_INVALID) { in qnoc_probe()
592 clk_bulk_disable_unprepare(qp->num_intf_clks, in qnoc_probe()
593 qp->intf_clks); in qnoc_probe()
598 data->nodes[i] = node; in qnoc_probe()
600 data->num_nodes = num_nodes; in qnoc_probe()
602 clk_bulk_disable_unprepare(qp->num_intf_clks, qp->intf_clks); in qnoc_probe()
611 if (of_get_child_count(dev->of_node) > 0) { in qnoc_probe()
612 ret = of_platform_populate(dev->of_node, NULL, NULL, dev); in qnoc_probe()
624 clk_disable_unprepare(qp->bus_clk); in qnoc_probe()
634 icc_provider_deregister(&qp->provider); in qnoc_remove()
635 icc_nodes_remove(&qp->provider); in qnoc_remove()
636 clk_disable_unprepare(qp->bus_clk); in qnoc_remove()