2 * Copyright (C) 2016 NVIDIA Corporation
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
9 #include <linux/clk-provider.h>
10 #include <linux/device.h>
11 #include <linux/seq_buf.h>
12 #include <linux/slab.h>
14 #include <soc/tegra/bpmp.h>
15 #include <soc/tegra/bpmp-abi.h>
17 #define TEGRA_BPMP_DUMP_CLOCK_INFO 0
19 #define TEGRA_BPMP_CLK_HAS_MUX BIT(0)
20 #define TEGRA_BPMP_CLK_HAS_SET_RATE BIT(1)
21 #define TEGRA_BPMP_CLK_IS_ROOT BIT(2)
23 struct tegra_bpmp_clk_info {
25 char name[MRQ_CLK_NAME_MAXLEN];
26 unsigned int parents[MRQ_CLK_MAX_PARENTS];
27 unsigned int num_parents;
31 struct tegra_bpmp_clk {
34 struct tegra_bpmp *bpmp;
37 unsigned int num_parents;
38 unsigned int *parents;
41 static inline struct tegra_bpmp_clk *to_tegra_bpmp_clk(struct clk_hw *hw)
43 return container_of(hw, struct tegra_bpmp_clk, hw);
46 struct tegra_bpmp_clk_message {
61 static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
62 const struct tegra_bpmp_clk_message *clk)
64 struct mrq_clk_request request;
65 struct tegra_bpmp_message msg;
68 memset(&request, 0, sizeof(request));
69 request.cmd_and_id = (clk->cmd << 24) | clk->id;
72 * The mrq_clk_request structure has an anonymous union at offset 4
73 * that contains all possible sub-command structures. Copy the data
74 * to that union. Ideally we'd be able to refer to it by name, but
75 * doing so would require changing the ABI header and increase the
78 memcpy(req + 4, clk->tx.data, clk->tx.size);
80 memset(&msg, 0, sizeof(msg));
82 msg.tx.data = &request;
83 msg.tx.size = sizeof(request);
84 msg.rx.data = clk->rx.data;
85 msg.rx.size = clk->rx.size;
87 return tegra_bpmp_transfer(bpmp, &msg);
90 static int tegra_bpmp_clk_prepare(struct clk_hw *hw)
92 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
93 struct tegra_bpmp_clk_message msg;
95 memset(&msg, 0, sizeof(msg));
96 msg.cmd = CMD_CLK_ENABLE;
99 return tegra_bpmp_clk_transfer(clk->bpmp, &msg);
102 static void tegra_bpmp_clk_unprepare(struct clk_hw *hw)
104 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
105 struct tegra_bpmp_clk_message msg;
108 memset(&msg, 0, sizeof(msg));
109 msg.cmd = CMD_CLK_DISABLE;
112 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
114 dev_err(clk->bpmp->dev, "failed to disable clock %s: %d\n",
115 clk_hw_get_name(hw), err);
118 static int tegra_bpmp_clk_is_prepared(struct clk_hw *hw)
120 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
121 struct cmd_clk_is_enabled_response response;
122 struct tegra_bpmp_clk_message msg;
125 memset(&msg, 0, sizeof(msg));
126 msg.cmd = CMD_CLK_IS_ENABLED;
128 msg.rx.data = &response;
129 msg.rx.size = sizeof(response);
131 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
135 return response.state;
138 static unsigned long tegra_bpmp_clk_recalc_rate(struct clk_hw *hw,
139 unsigned long parent_rate)
141 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
142 struct cmd_clk_get_rate_response response;
143 struct cmd_clk_get_rate_request request;
144 struct tegra_bpmp_clk_message msg;
147 memset(&msg, 0, sizeof(msg));
148 msg.cmd = CMD_CLK_GET_RATE;
150 msg.tx.data = &request;
151 msg.tx.size = sizeof(request);
152 msg.rx.data = &response;
153 msg.rx.size = sizeof(response);
155 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
159 return response.rate;
162 static long tegra_bpmp_clk_round_rate(struct clk_hw *hw, unsigned long rate,
163 unsigned long *parent_rate)
165 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
166 struct cmd_clk_round_rate_response response;
167 struct cmd_clk_round_rate_request request;
168 struct tegra_bpmp_clk_message msg;
171 memset(&request, 0, sizeof(request));
174 memset(&msg, 0, sizeof(msg));
175 msg.cmd = CMD_CLK_ROUND_RATE;
177 msg.tx.data = &request;
178 msg.tx.size = sizeof(request);
179 msg.rx.data = &response;
180 msg.rx.size = sizeof(response);
182 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
186 return response.rate;
189 static int tegra_bpmp_clk_set_parent(struct clk_hw *hw, u8 index)
191 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
192 struct cmd_clk_set_parent_response response;
193 struct cmd_clk_set_parent_request request;
194 struct tegra_bpmp_clk_message msg;
197 memset(&request, 0, sizeof(request));
198 request.parent_id = clk->parents[index];
200 memset(&msg, 0, sizeof(msg));
201 msg.cmd = CMD_CLK_SET_PARENT;
203 msg.tx.data = &request;
204 msg.tx.size = sizeof(request);
205 msg.rx.data = &response;
206 msg.rx.size = sizeof(response);
208 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
212 /* XXX check parent ID in response */
217 static u8 tegra_bpmp_clk_get_parent(struct clk_hw *hw)
219 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
220 struct cmd_clk_get_parent_response response;
221 struct tegra_bpmp_clk_message msg;
225 memset(&msg, 0, sizeof(msg));
226 msg.cmd = CMD_CLK_GET_PARENT;
228 msg.rx.data = &response;
229 msg.rx.size = sizeof(response);
231 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
233 dev_err(clk->bpmp->dev, "failed to get parent for %s: %d\n",
234 clk_hw_get_name(hw), err);
238 for (i = 0; i < clk->num_parents; i++)
239 if (clk->parents[i] == response.parent_id)
245 static int tegra_bpmp_clk_set_rate(struct clk_hw *hw, unsigned long rate,
246 unsigned long parent_rate)
248 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
249 struct cmd_clk_set_rate_response response;
250 struct cmd_clk_set_rate_request request;
251 struct tegra_bpmp_clk_message msg;
253 memset(&request, 0, sizeof(request));
256 memset(&msg, 0, sizeof(msg));
257 msg.cmd = CMD_CLK_SET_RATE;
259 msg.tx.data = &request;
260 msg.tx.size = sizeof(request);
261 msg.rx.data = &response;
262 msg.rx.size = sizeof(response);
264 return tegra_bpmp_clk_transfer(clk->bpmp, &msg);
267 static const struct clk_ops tegra_bpmp_clk_gate_ops = {
268 .prepare = tegra_bpmp_clk_prepare,
269 .unprepare = tegra_bpmp_clk_unprepare,
270 .is_prepared = tegra_bpmp_clk_is_prepared,
271 .recalc_rate = tegra_bpmp_clk_recalc_rate,
274 static const struct clk_ops tegra_bpmp_clk_mux_ops = {
275 .prepare = tegra_bpmp_clk_prepare,
276 .unprepare = tegra_bpmp_clk_unprepare,
277 .is_prepared = tegra_bpmp_clk_is_prepared,
278 .recalc_rate = tegra_bpmp_clk_recalc_rate,
279 .set_parent = tegra_bpmp_clk_set_parent,
280 .get_parent = tegra_bpmp_clk_get_parent,
283 static const struct clk_ops tegra_bpmp_clk_rate_ops = {
284 .prepare = tegra_bpmp_clk_prepare,
285 .unprepare = tegra_bpmp_clk_unprepare,
286 .is_prepared = tegra_bpmp_clk_is_prepared,
287 .recalc_rate = tegra_bpmp_clk_recalc_rate,
288 .round_rate = tegra_bpmp_clk_round_rate,
289 .set_rate = tegra_bpmp_clk_set_rate,
292 static const struct clk_ops tegra_bpmp_clk_mux_rate_ops = {
293 .prepare = tegra_bpmp_clk_prepare,
294 .unprepare = tegra_bpmp_clk_unprepare,
295 .is_prepared = tegra_bpmp_clk_is_prepared,
296 .recalc_rate = tegra_bpmp_clk_recalc_rate,
297 .round_rate = tegra_bpmp_clk_round_rate,
298 .set_parent = tegra_bpmp_clk_set_parent,
299 .get_parent = tegra_bpmp_clk_get_parent,
300 .set_rate = tegra_bpmp_clk_set_rate,
303 static int tegra_bpmp_clk_get_max_id(struct tegra_bpmp *bpmp)
305 struct cmd_clk_get_max_clk_id_response response;
306 struct tegra_bpmp_clk_message msg;
309 memset(&msg, 0, sizeof(msg));
310 msg.cmd = CMD_CLK_GET_MAX_CLK_ID;
311 msg.rx.data = &response;
312 msg.rx.size = sizeof(response);
314 err = tegra_bpmp_clk_transfer(bpmp, &msg);
318 if (response.max_id > INT_MAX)
321 return response.max_id;
324 static int tegra_bpmp_clk_get_info(struct tegra_bpmp *bpmp, unsigned int id,
325 struct tegra_bpmp_clk_info *info)
327 struct cmd_clk_get_all_info_response response;
328 struct tegra_bpmp_clk_message msg;
332 memset(&msg, 0, sizeof(msg));
333 msg.cmd = CMD_CLK_GET_ALL_INFO;
335 msg.rx.data = &response;
336 msg.rx.size = sizeof(response);
338 err = tegra_bpmp_clk_transfer(bpmp, &msg);
342 strlcpy(info->name, response.name, MRQ_CLK_NAME_MAXLEN);
343 info->num_parents = response.num_parents;
345 for (i = 0; i < info->num_parents; i++)
346 info->parents[i] = response.parents[i];
348 info->flags = response.flags;
353 static void tegra_bpmp_clk_info_dump(struct tegra_bpmp *bpmp,
355 const struct tegra_bpmp_clk_info *info)
357 const char *prefix = "";
362 seq_buf_init(&buf, flags, sizeof(flags));
365 seq_buf_printf(&buf, "(");
367 if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) {
368 seq_buf_printf(&buf, "%smux", prefix);
372 if ((info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE) == 0) {
373 seq_buf_printf(&buf, "%sfixed", prefix);
377 if (info->flags & TEGRA_BPMP_CLK_IS_ROOT) {
378 seq_buf_printf(&buf, "%sroot", prefix);
383 seq_buf_printf(&buf, ")");
385 dev_printk(level, bpmp->dev, "%03u: %s\n", info->id, info->name);
386 dev_printk(level, bpmp->dev, " flags: %lx %s\n", info->flags, flags);
387 dev_printk(level, bpmp->dev, " parents: %u\n", info->num_parents);
389 for (i = 0; i < info->num_parents; i++)
390 dev_printk(level, bpmp->dev, " %03u\n", info->parents[i]);
393 static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp,
394 struct tegra_bpmp_clk_info **clocksp)
396 struct tegra_bpmp_clk_info *clocks;
397 unsigned int max_id, id, count = 0;
398 unsigned int holes = 0;
401 err = tegra_bpmp_clk_get_max_id(bpmp);
407 dev_dbg(bpmp->dev, "maximum clock ID: %u\n", max_id);
409 clocks = kcalloc(max_id + 1, sizeof(*clocks), GFP_KERNEL);
413 for (id = 0; id <= max_id; id++) {
414 struct tegra_bpmp_clk_info *info = &clocks[count];
416 err = tegra_bpmp_clk_get_info(bpmp, id, info);
418 dev_err(bpmp->dev, "failed to query clock %u: %d\n",
423 if (info->num_parents >= U8_MAX) {
425 "clock %u has too many parents (%u, max: %u)\n",
426 id, info->num_parents, U8_MAX);
430 /* clock not exposed by BPMP */
431 if (info->name[0] == '\0') {
439 if (TEGRA_BPMP_DUMP_CLOCK_INFO)
440 tegra_bpmp_clk_info_dump(bpmp, KERN_DEBUG, info);
443 dev_dbg(bpmp->dev, "holes: %u\n", holes);
449 static const struct tegra_bpmp_clk_info *
450 tegra_bpmp_clk_find(const struct tegra_bpmp_clk_info *clocks,
451 unsigned int num_clocks, unsigned int id)
455 for (i = 0; i < num_clocks; i++)
456 if (clocks[i].id == id)
462 static struct tegra_bpmp_clk *
463 tegra_bpmp_clk_register(struct tegra_bpmp *bpmp,
464 const struct tegra_bpmp_clk_info *info,
465 const struct tegra_bpmp_clk_info *clocks,
466 unsigned int num_clocks)
468 struct tegra_bpmp_clk *clk;
469 struct clk_init_data init;
470 const char **parents;
474 clk = devm_kzalloc(bpmp->dev, sizeof(*clk), GFP_KERNEL);
476 return ERR_PTR(-ENOMEM);
481 clk->parents = devm_kcalloc(bpmp->dev, info->num_parents,
482 sizeof(*clk->parents), GFP_KERNEL);
484 return ERR_PTR(-ENOMEM);
486 clk->num_parents = info->num_parents;
488 /* hardware clock initialization */
489 memset(&init, 0, sizeof(init));
490 init.name = info->name;
491 clk->hw.init = &init;
493 if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) {
494 if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE)
495 init.ops = &tegra_bpmp_clk_mux_rate_ops;
497 init.ops = &tegra_bpmp_clk_mux_ops;
499 if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE)
500 init.ops = &tegra_bpmp_clk_rate_ops;
502 init.ops = &tegra_bpmp_clk_gate_ops;
505 init.num_parents = info->num_parents;
507 parents = kcalloc(info->num_parents, sizeof(*parents), GFP_KERNEL);
509 return ERR_PTR(-ENOMEM);
511 for (i = 0; i < info->num_parents; i++) {
512 const struct tegra_bpmp_clk_info *parent;
514 /* keep a private copy of the ID to parent index map */
515 clk->parents[i] = info->parents[i];
517 parent = tegra_bpmp_clk_find(clocks, num_clocks,
520 dev_err(bpmp->dev, "no parent %u found for %u\n",
521 info->parents[i], info->id);
525 parents[i] = parent->name;
528 init.parent_names = parents;
530 err = devm_clk_hw_register(bpmp->dev, &clk->hw);
540 static int tegra_bpmp_register_clocks(struct tegra_bpmp *bpmp,
541 struct tegra_bpmp_clk_info *infos,
544 struct tegra_bpmp_clk *clk;
547 bpmp->num_clocks = count;
549 bpmp->clocks = devm_kcalloc(bpmp->dev, count, sizeof(clk), GFP_KERNEL);
553 for (i = 0; i < count; i++) {
554 struct tegra_bpmp_clk_info *info = &infos[i];
556 clk = tegra_bpmp_clk_register(bpmp, info, infos, count);
559 "failed to register clock %u (%s): %ld\n",
560 info->id, info->name, PTR_ERR(clk));
564 bpmp->clocks[i] = clk;
570 static void tegra_bpmp_unregister_clocks(struct tegra_bpmp *bpmp)
574 for (i = 0; i < bpmp->num_clocks; i++)
575 clk_hw_unregister(&bpmp->clocks[i]->hw);
578 static struct clk_hw *tegra_bpmp_clk_of_xlate(struct of_phandle_args *clkspec,
581 unsigned int id = clkspec->args[0], i;
582 struct tegra_bpmp *bpmp = data;
584 for (i = 0; i < bpmp->num_clocks; i++)
585 if (bpmp->clocks[i]->id == id)
586 return &bpmp->clocks[i]->hw;
591 int tegra_bpmp_init_clocks(struct tegra_bpmp *bpmp)
593 struct tegra_bpmp_clk_info *clocks;
597 err = tegra_bpmp_probe_clocks(bpmp, &clocks);
603 dev_dbg(bpmp->dev, "%u clocks probed\n", count);
605 err = tegra_bpmp_register_clocks(bpmp, clocks, count);
609 err = of_clk_add_hw_provider(bpmp->dev->of_node,
610 tegra_bpmp_clk_of_xlate,
613 tegra_bpmp_unregister_clocks(bpmp);