Lines Matching +full:rx +full:- +full:clock +full:- +full:name

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2016-2022 NVIDIA Corporation
6 #include <linux/clk-provider.h>
12 #include <soc/tegra/bpmp-abi.h>
22 char name[MRQ_CLK_NAME_MAXLEN]; member
56 } rx; member
68 request.cmd_and_id = (clk->cmd << 24) | clk->id; in tegra_bpmp_clk_transfer()
72 * that contains all possible sub-command structures. Copy the data in tegra_bpmp_clk_transfer()
73 * to that union. Ideally we'd be able to refer to it by name, but in tegra_bpmp_clk_transfer()
77 memcpy(req + 4, clk->tx.data, clk->tx.size); in tegra_bpmp_clk_transfer()
83 msg.rx.data = clk->rx.data; in tegra_bpmp_clk_transfer()
84 msg.rx.size = clk->rx.size; in tegra_bpmp_clk_transfer()
89 else if (msg.rx.ret < 0) in tegra_bpmp_clk_transfer()
90 return -EINVAL; in tegra_bpmp_clk_transfer()
102 msg.id = clk->id; in tegra_bpmp_clk_prepare()
104 return tegra_bpmp_clk_transfer(clk->bpmp, &msg); in tegra_bpmp_clk_prepare()
115 msg.id = clk->id; in tegra_bpmp_clk_unprepare()
117 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); in tegra_bpmp_clk_unprepare()
119 dev_err(clk->bpmp->dev, "failed to disable clock %s: %d\n", in tegra_bpmp_clk_unprepare()
132 msg.id = clk->id; in tegra_bpmp_clk_is_prepared()
133 msg.rx.data = &response; in tegra_bpmp_clk_is_prepared()
134 msg.rx.size = sizeof(response); in tegra_bpmp_clk_is_prepared()
136 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); in tegra_bpmp_clk_is_prepared()
154 msg.id = clk->id; in tegra_bpmp_clk_recalc_rate()
157 msg.rx.data = &response; in tegra_bpmp_clk_recalc_rate()
158 msg.rx.size = sizeof(response); in tegra_bpmp_clk_recalc_rate()
160 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); in tegra_bpmp_clk_recalc_rate()
177 rate = clamp(rate_req->rate, rate_req->min_rate, rate_req->max_rate); in tegra_bpmp_clk_determine_rate()
184 msg.id = clk->id; in tegra_bpmp_clk_determine_rate()
187 msg.rx.data = &response; in tegra_bpmp_clk_determine_rate()
188 msg.rx.size = sizeof(response); in tegra_bpmp_clk_determine_rate()
190 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); in tegra_bpmp_clk_determine_rate()
194 rate_req->rate = (unsigned long)response.rate; in tegra_bpmp_clk_determine_rate()
208 request.parent_id = clk->parents[index]; in tegra_bpmp_clk_set_parent()
212 msg.id = clk->id; in tegra_bpmp_clk_set_parent()
215 msg.rx.data = &response; in tegra_bpmp_clk_set_parent()
216 msg.rx.size = sizeof(response); in tegra_bpmp_clk_set_parent()
218 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); in tegra_bpmp_clk_set_parent()
237 msg.id = clk->id; in tegra_bpmp_clk_get_parent()
238 msg.rx.data = &response; in tegra_bpmp_clk_get_parent()
239 msg.rx.size = sizeof(response); in tegra_bpmp_clk_get_parent()
241 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); in tegra_bpmp_clk_get_parent()
243 dev_err(clk->bpmp->dev, "failed to get parent for %s: %d\n", in tegra_bpmp_clk_get_parent()
248 for (i = 0; i < clk->num_parents; i++) in tegra_bpmp_clk_get_parent()
249 if (clk->parents[i] == response.parent_id) in tegra_bpmp_clk_get_parent()
268 msg.id = clk->id; in tegra_bpmp_clk_set_rate()
271 msg.rx.data = &response; in tegra_bpmp_clk_set_rate()
272 msg.rx.size = sizeof(response); in tegra_bpmp_clk_set_rate()
274 return tegra_bpmp_clk_transfer(clk->bpmp, &msg); in tegra_bpmp_clk_set_rate()
339 msg.rx.data = &response; in tegra_bpmp_clk_get_max_id()
340 msg.rx.size = sizeof(response); in tegra_bpmp_clk_get_max_id()
347 return -E2BIG; in tegra_bpmp_clk_get_max_id()
363 msg.rx.data = &response; in tegra_bpmp_clk_get_info()
364 msg.rx.size = sizeof(response); in tegra_bpmp_clk_get_info()
370 strscpy(info->name, response.name, MRQ_CLK_NAME_MAXLEN); in tegra_bpmp_clk_get_info()
371 info->num_parents = response.num_parents; in tegra_bpmp_clk_get_info()
373 for (i = 0; i < info->num_parents; i++) in tegra_bpmp_clk_get_info()
374 info->parents[i] = response.parents[i]; in tegra_bpmp_clk_get_info()
376 info->flags = response.flags; in tegra_bpmp_clk_get_info()
392 if (info->flags) in tegra_bpmp_clk_info_dump()
395 if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) { in tegra_bpmp_clk_info_dump()
400 if ((info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE) == 0) { in tegra_bpmp_clk_info_dump()
405 if (info->flags & TEGRA_BPMP_CLK_IS_ROOT) { in tegra_bpmp_clk_info_dump()
410 if (info->flags) in tegra_bpmp_clk_info_dump()
413 dev_printk(level, bpmp->dev, "%03u: %s\n", info->id, info->name); in tegra_bpmp_clk_info_dump()
414 dev_printk(level, bpmp->dev, " flags: %lx %s\n", info->flags, flags); in tegra_bpmp_clk_info_dump()
415 dev_printk(level, bpmp->dev, " parents: %u\n", info->num_parents); in tegra_bpmp_clk_info_dump()
417 for (i = 0; i < info->num_parents; i++) in tegra_bpmp_clk_info_dump()
418 dev_printk(level, bpmp->dev, " %03u\n", info->parents[i]); in tegra_bpmp_clk_info_dump()
435 dev_dbg(bpmp->dev, "maximum clock ID: %u\n", max_id); in tegra_bpmp_probe_clocks()
439 return -ENOMEM; in tegra_bpmp_probe_clocks()
448 if (info->num_parents >= U8_MAX) { in tegra_bpmp_probe_clocks()
449 dev_err(bpmp->dev, in tegra_bpmp_probe_clocks()
450 "clock %u has too many parents (%u, max: %u)\n", in tegra_bpmp_probe_clocks()
451 id, info->num_parents, U8_MAX); in tegra_bpmp_probe_clocks()
455 /* clock not exposed by BPMP */ in tegra_bpmp_probe_clocks()
456 if (info->name[0] == '\0') { in tegra_bpmp_probe_clocks()
461 info->id = id; in tegra_bpmp_probe_clocks()
468 dev_dbg(bpmp->dev, "holes: %u\n", holes); in tegra_bpmp_probe_clocks()
513 clk = devm_kzalloc(bpmp->dev, sizeof(*clk), GFP_KERNEL); in tegra_bpmp_clk_register()
515 return ERR_PTR(-ENOMEM); in tegra_bpmp_clk_register()
517 clk->id = info->id; in tegra_bpmp_clk_register()
518 clk->bpmp = bpmp; in tegra_bpmp_clk_register()
520 clk->parents = devm_kcalloc(bpmp->dev, info->num_parents, in tegra_bpmp_clk_register()
521 sizeof(*clk->parents), GFP_KERNEL); in tegra_bpmp_clk_register()
522 if (!clk->parents) in tegra_bpmp_clk_register()
523 return ERR_PTR(-ENOMEM); in tegra_bpmp_clk_register()
525 clk->num_parents = info->num_parents; in tegra_bpmp_clk_register()
527 /* hardware clock initialization */ in tegra_bpmp_clk_register()
529 init.name = info->name; in tegra_bpmp_clk_register()
530 clk->hw.init = &init; in tegra_bpmp_clk_register()
531 if (info->flags & BPMP_CLK_STATE_CHANGE_DENIED) { in tegra_bpmp_clk_register()
532 if ((info->flags & BPMP_CLK_RATE_PARENT_CHANGE_DENIED) == 0) { in tegra_bpmp_clk_register()
533 dev_WARN(bpmp->dev, in tegra_bpmp_clk_register()
534 …"Firmware bug! Inconsistent permission bits for clock %s. State and parent/rate changes disabled.", in tegra_bpmp_clk_register()
535 init.name); in tegra_bpmp_clk_register()
537 if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) in tegra_bpmp_clk_register()
541 } else if (info->flags & BPMP_CLK_RATE_PARENT_CHANGE_DENIED) { in tegra_bpmp_clk_register()
542 if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) in tegra_bpmp_clk_register()
546 } else if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) { in tegra_bpmp_clk_register()
547 if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE) in tegra_bpmp_clk_register()
552 if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE) in tegra_bpmp_clk_register()
558 init.num_parents = info->num_parents; in tegra_bpmp_clk_register()
560 parents = kcalloc(info->num_parents, sizeof(*parents), GFP_KERNEL); in tegra_bpmp_clk_register()
562 return ERR_PTR(-ENOMEM); in tegra_bpmp_clk_register()
564 for (i = 0; i < info->num_parents; i++) { in tegra_bpmp_clk_register()
568 clk->parents[i] = info->parents[i]; in tegra_bpmp_clk_register()
571 info->parents[i]); in tegra_bpmp_clk_register()
573 dev_err(bpmp->dev, "no parent %u found for %u\n", in tegra_bpmp_clk_register()
574 info->parents[i], info->id); in tegra_bpmp_clk_register()
578 parents[i] = parent->name; in tegra_bpmp_clk_register()
583 err = devm_clk_hw_register(bpmp->dev, &clk->hw); in tegra_bpmp_clk_register()
602 if (bpmp->clocks[i]) { in tegra_bpmp_register_clocks_one()
608 for (j = 0; j < info->num_parents; ++j) { in tegra_bpmp_register_clocks_one()
609 unsigned int p_id = info->parents[j]; in tegra_bpmp_register_clocks_one()
618 dev_err(bpmp->dev, in tegra_bpmp_register_clocks_one()
619 "failed to register clock %u (%s): %ld\n", in tegra_bpmp_register_clocks_one()
620 info->id, info->name, PTR_ERR(clk)); in tegra_bpmp_register_clocks_one()
622 * bpmp->clocks[i] to avoid re-attempting the in tegra_bpmp_register_clocks_one()
627 bpmp->clocks[i] = clk; in tegra_bpmp_register_clocks_one()
636 bpmp->num_clocks = count; in tegra_bpmp_register_clocks()
638 bpmp->clocks = devm_kcalloc(bpmp->dev, count, sizeof(struct tegra_bpmp_clk), GFP_KERNEL); in tegra_bpmp_register_clocks()
639 if (!bpmp->clocks) in tegra_bpmp_register_clocks()
640 return -ENOMEM; in tegra_bpmp_register_clocks()
653 for (i = 0; i < bpmp->num_clocks; i++) in tegra_bpmp_unregister_clocks()
654 clk_hw_unregister(&bpmp->clocks[i]->hw); in tegra_bpmp_unregister_clocks()
660 unsigned int id = clkspec->args[0], i; in tegra_bpmp_clk_of_xlate()
663 for (i = 0; i < bpmp->num_clocks; i++) { in tegra_bpmp_clk_of_xlate()
664 struct tegra_bpmp_clk *clk = bpmp->clocks[i]; in tegra_bpmp_clk_of_xlate()
669 if (clk->id == id) in tegra_bpmp_clk_of_xlate()
670 return &clk->hw; in tegra_bpmp_clk_of_xlate()
688 dev_dbg(bpmp->dev, "%u clocks probed\n", count); in tegra_bpmp_init_clocks()
694 err = of_clk_add_hw_provider(bpmp->dev->of_node, in tegra_bpmp_init_clocks()