]> Git Repo - linux.git/blob - drivers/clk/ti/clk.c
Linux 6.14-rc3
[linux.git] / drivers / clk / ti / clk.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * TI clock support
4  *
5  * Copyright (C) 2013 Texas Instruments, Inc.
6  *
7  * Tero Kristo <[email protected]>
8  */
9
10 #include <linux/cleanup.h>
11 #include <linux/clk.h>
12 #include <linux/clk-provider.h>
13 #include <linux/clkdev.h>
14 #include <linux/clk/ti.h>
15 #include <linux/io.h>
16 #include <linux/of.h>
17 #include <linux/of_address.h>
18 #include <linux/list.h>
19 #include <linux/minmax.h>
20 #include <linux/regmap.h>
21 #include <linux/string_helpers.h>
22 #include <linux/memblock.h>
23 #include <linux/device.h>
24
25 #include "clock.h"
26
27 #undef pr_fmt
28 #define pr_fmt(fmt) "%s: " fmt, __func__
29
30 static LIST_HEAD(clk_hw_omap_clocks);
31 struct ti_clk_ll_ops *ti_clk_ll_ops;
32 static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS];
33
34 struct ti_clk_features ti_clk_features;
35
36 struct clk_iomap {
37         struct regmap *regmap;
38         void __iomem *mem;
39 };
40
41 static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS];
42
43 static void clk_memmap_writel(u32 val, const struct clk_omap_reg *reg)
44 {
45         struct clk_iomap *io = clk_memmaps[reg->index];
46
47         if (reg->ptr)
48                 writel_relaxed(val, reg->ptr);
49         else if (io->regmap)
50                 regmap_write(io->regmap, reg->offset, val);
51         else
52                 writel_relaxed(val, io->mem + reg->offset);
53 }
54
55 static void _clk_rmw(u32 val, u32 mask, void __iomem *ptr)
56 {
57         u32 v;
58
59         v = readl_relaxed(ptr);
60         v &= ~mask;
61         v |= val;
62         writel_relaxed(v, ptr);
63 }
64
65 static void clk_memmap_rmw(u32 val, u32 mask, const struct clk_omap_reg *reg)
66 {
67         struct clk_iomap *io = clk_memmaps[reg->index];
68
69         if (reg->ptr) {
70                 _clk_rmw(val, mask, reg->ptr);
71         } else if (io->regmap) {
72                 regmap_update_bits(io->regmap, reg->offset, mask, val);
73         } else {
74                 _clk_rmw(val, mask, io->mem + reg->offset);
75         }
76 }
77
78 static u32 clk_memmap_readl(const struct clk_omap_reg *reg)
79 {
80         u32 val;
81         struct clk_iomap *io = clk_memmaps[reg->index];
82
83         if (reg->ptr)
84                 val = readl_relaxed(reg->ptr);
85         else if (io->regmap)
86                 regmap_read(io->regmap, reg->offset, &val);
87         else
88                 val = readl_relaxed(io->mem + reg->offset);
89
90         return val;
91 }
92
93 /**
94  * ti_clk_setup_ll_ops - setup low level clock operations
95  * @ops: low level clock ops descriptor
96  *
97  * Sets up low level clock operations for TI clock driver. This is used
98  * to provide various callbacks for the clock driver towards platform
99  * specific code. Returns 0 on success, -EBUSY if ll_ops have been
100  * registered already.
101  */
102 int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops)
103 {
104         if (ti_clk_ll_ops) {
105                 pr_err("Attempt to register ll_ops multiple times.\n");
106                 return -EBUSY;
107         }
108
109         ti_clk_ll_ops = ops;
110         ops->clk_readl = clk_memmap_readl;
111         ops->clk_writel = clk_memmap_writel;
112         ops->clk_rmw = clk_memmap_rmw;
113
114         return 0;
115 }
116
117 /*
118  * Eventually we could standardize to using '_' for clk-*.c files to follow the
119  * TRM naming.
120  */
121 static struct device_node *ti_find_clock_provider(struct device_node *from,
122                                                   const char *name)
123 {
124         char *tmp __free(kfree) = NULL;
125         struct device_node *np;
126         bool found = false;
127         const char *n;
128         char *p;
129
130         tmp = kstrdup_and_replace(name, '-', '_', GFP_KERNEL);
131         if (!tmp)
132                 return NULL;
133
134         /* Ignore a possible address for the node name */
135         p = strchr(tmp, '@');
136         if (p)
137                 *p = '\0';
138
139         /* Node named "clock" with "clock-output-names" */
140         for_each_of_allnodes_from(from, np) {
141                 if (of_property_read_string_index(np, "clock-output-names",
142                                                   0, &n))
143                         continue;
144
145                 if (!strncmp(n, tmp, strlen(tmp))) {
146                         of_node_get(np);
147                         found = true;
148                         break;
149                 }
150         }
151
152         if (found) {
153                 of_node_put(from);
154                 return np;
155         }
156
157         /* Fall back to using old node name base provider name */
158         return of_find_node_by_name(from, tmp);
159 }
160
161 /**
162  * ti_dt_clocks_register - register DT alias clocks during boot
163  * @oclks: list of clocks to register
164  *
165  * Register alias or non-standard DT clock entries during boot. By
166  * default, DT clocks are found based on their clock-output-names
167  * property, or the clock node name for legacy cases. If any
168  * additional con-id / dev-id -> clock mapping is required, use this
169  * function to list these.
170  */
171 void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
172 {
173         struct ti_dt_clk *c;
174         struct device_node *node, *parent, *child;
175         struct clk *clk;
176         struct of_phandle_args clkspec;
177         char buf[64];
178         char *ptr;
179         char *tags[2];
180         int i;
181         int num_args;
182         int ret;
183         static bool clkctrl_nodes_missing;
184         static bool has_clkctrl_data;
185         static bool compat_mode;
186
187         compat_mode = ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT;
188
189         for (c = oclks; c->node_name != NULL; c++) {
190                 strcpy(buf, c->node_name);
191                 ptr = buf;
192                 for (i = 0; i < 2; i++)
193                         tags[i] = NULL;
194                 num_args = 0;
195                 while (*ptr) {
196                         if (*ptr == ':') {
197                                 if (num_args >= 2) {
198                                         pr_warn("Bad number of tags on %s\n",
199                                                 c->node_name);
200                                         return;
201                                 }
202                                 tags[num_args++] = ptr + 1;
203                                 *ptr = 0;
204                         }
205                         ptr++;
206                 }
207
208                 if (num_args && clkctrl_nodes_missing)
209                         continue;
210
211                 node = ti_find_clock_provider(NULL, buf);
212                 if (num_args && compat_mode) {
213                         parent = node;
214                         child = of_get_child_by_name(parent, "clock");
215                         if (!child)
216                                 child = of_get_child_by_name(parent, "clk");
217                         if (child) {
218                                 of_node_put(parent);
219                                 node = child;
220                         }
221                 }
222
223                 clkspec.np = node;
224                 clkspec.args_count = num_args;
225                 for (i = 0; i < num_args; i++) {
226                         ret = kstrtoint(tags[i], i ? 10 : 16, clkspec.args + i);
227                         if (ret) {
228                                 pr_warn("Bad tag in %s at %d: %s\n",
229                                         c->node_name, i, tags[i]);
230                                 of_node_put(node);
231                                 return;
232                         }
233                 }
234                 clk = of_clk_get_from_provider(&clkspec);
235                 of_node_put(node);
236                 if (!IS_ERR(clk)) {
237                         c->lk.clk = clk;
238                         clkdev_add(&c->lk);
239                 } else {
240                         if (num_args && !has_clkctrl_data) {
241                                 struct device_node *np;
242
243                                 np = of_find_compatible_node(NULL, NULL,
244                                                              "ti,clkctrl");
245                                 if (np) {
246                                         has_clkctrl_data = true;
247                                         of_node_put(np);
248                                 } else {
249                                         clkctrl_nodes_missing = true;
250
251                                         pr_warn("missing clkctrl nodes, please update your dts.\n");
252                                         continue;
253                                 }
254                         }
255
256                         pr_warn("failed to lookup clock node %s, ret=%ld\n",
257                                 c->node_name, PTR_ERR(clk));
258                 }
259         }
260 }
261
262 struct clk_init_item {
263         struct device_node *node;
264         void *user;
265         ti_of_clk_init_cb_t func;
266         struct list_head link;
267 };
268
269 static LIST_HEAD(retry_list);
270
271 /**
272  * ti_clk_retry_init - retries a failed clock init at later phase
273  * @node: device node for the clock
274  * @user: user data pointer
275  * @func: init function to be called for the clock
276  *
277  * Adds a failed clock init to the retry list. The retry list is parsed
278  * once all the other clocks have been initialized.
279  */
280 int __init ti_clk_retry_init(struct device_node *node, void *user,
281                              ti_of_clk_init_cb_t func)
282 {
283         struct clk_init_item *retry;
284
285         pr_debug("%pOFn: adding to retry list...\n", node);
286         retry = kzalloc(sizeof(*retry), GFP_KERNEL);
287         if (!retry)
288                 return -ENOMEM;
289
290         retry->node = node;
291         retry->func = func;
292         retry->user = user;
293         list_add(&retry->link, &retry_list);
294
295         return 0;
296 }
297
298 /**
299  * ti_clk_get_reg_addr - get register address for a clock register
300  * @node: device node for the clock
301  * @index: register index from the clock node
302  * @reg: pointer to target register struct
303  *
304  * Builds clock register address from device tree information, and returns
305  * the data via the provided output pointer @reg. Returns 0 on success,
306  * negative error value on failure.
307  */
308 int ti_clk_get_reg_addr(struct device_node *node, int index,
309                         struct clk_omap_reg *reg)
310 {
311         u32 clksel_addr, val;
312         bool is_clksel = false;
313         int i, err;
314
315         for (i = 0; i < CLK_MAX_MEMMAPS; i++) {
316                 if (clocks_node_ptr[i] == node->parent)
317                         break;
318                 if (clocks_node_ptr[i] == node->parent->parent)
319                         break;
320         }
321
322         if (i == CLK_MAX_MEMMAPS) {
323                 pr_err("clk-provider not found for %pOFn!\n", node);
324                 return -ENOENT;
325         }
326
327         reg->index = i;
328
329         if (of_device_is_compatible(node->parent, "ti,clksel")) {
330                 err = of_property_read_u32_index(node->parent, "reg", index, &clksel_addr);
331                 if (err) {
332                         pr_err("%pOFn parent clksel must have reg[%d]!\n", node, index);
333                         return -EINVAL;
334                 }
335                 is_clksel = true;
336         }
337
338         err = of_property_read_u32_index(node, "reg", index, &val);
339         if (err && is_clksel) {
340                 /* Legacy clksel with no reg and a possible ti,bit-shift property */
341                 reg->offset = clksel_addr;
342                 reg->bit = ti_clk_get_legacy_bit_shift(node);
343                 reg->ptr = NULL;
344
345                 return 0;
346         }
347
348         /* Updated clksel clock with a proper reg property */
349         if (is_clksel) {
350                 reg->offset = clksel_addr;
351                 reg->bit = val;
352                 reg->ptr = NULL;
353                 return 0;
354         }
355
356         /* Other clocks that may or may not have ti,bit-shift property  */
357         reg->offset = val;
358         reg->bit = ti_clk_get_legacy_bit_shift(node);
359         reg->ptr = NULL;
360
361         return 0;
362 }
363
364 /**
365  * ti_clk_get_legacy_bit_shift - get bit shift for a clock register
366  * @node: device node for the clock
367  *
368  * Gets the clock register bit shift using the legacy ti,bit-shift
369  * property. Only needed for legacy clock, and can be eventually
370  * dropped once all the composite clocks use a clksel node with a
371  * proper reg property.
372  */
373 int ti_clk_get_legacy_bit_shift(struct device_node *node)
374 {
375         int err;
376         u32 val;
377
378         err = of_property_read_u32(node, "ti,bit-shift", &val);
379         if (!err && in_range(val, 0, 32))
380                 return val;
381
382         return 0;
383 }
384
385 void ti_clk_latch(struct clk_omap_reg *reg, s8 shift)
386 {
387         u32 latch;
388
389         if (shift < 0)
390                 return;
391
392         latch = 1 << shift;
393
394         ti_clk_ll_ops->clk_rmw(latch, latch, reg);
395         ti_clk_ll_ops->clk_rmw(0, latch, reg);
396         ti_clk_ll_ops->clk_readl(reg); /* OCP barrier */
397 }
398
399 /**
400  * omap2_clk_provider_init - init master clock provider
401  * @parent: master node
402  * @index: internal index for clk_reg_ops
403  * @syscon: syscon regmap pointer for accessing clock registers
404  * @mem: iomem pointer for the clock provider memory area, only used if
405  *       syscon is not provided
406  *
407  * Initializes a master clock IP block. This basically sets up the
408  * mapping from clocks node to the memory map index. All the clocks
409  * are then initialized through the common of_clk_init call, and the
410  * clocks will access their memory maps based on the node layout.
411  * Returns 0 in success.
412  */
413 int __init omap2_clk_provider_init(struct device_node *parent, int index,
414                                    struct regmap *syscon, void __iomem *mem)
415 {
416         struct device_node *clocks;
417         struct clk_iomap *io;
418
419         /* get clocks for this parent */
420         clocks = of_get_child_by_name(parent, "clocks");
421         if (!clocks) {
422                 pr_err("%pOFn missing 'clocks' child node.\n", parent);
423                 return -EINVAL;
424         }
425
426         /* add clocks node info */
427         clocks_node_ptr[index] = clocks;
428
429         io = kzalloc(sizeof(*io), GFP_KERNEL);
430         if (!io)
431                 return -ENOMEM;
432
433         io->regmap = syscon;
434         io->mem = mem;
435
436         clk_memmaps[index] = io;
437
438         return 0;
439 }
440
441 /**
442  * omap2_clk_legacy_provider_init - initialize a legacy clock provider
443  * @index: index for the clock provider
444  * @mem: iomem pointer for the clock provider memory area
445  *
446  * Initializes a legacy clock provider memory mapping.
447  */
448 void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem)
449 {
450         struct clk_iomap *io;
451
452         io = memblock_alloc_or_panic(sizeof(*io), SMP_CACHE_BYTES);
453
454         io->mem = mem;
455
456         clk_memmaps[index] = io;
457 }
458
459 /**
460  * ti_dt_clk_init_retry_clks - init clocks from the retry list
461  *
462  * Initializes any clocks that have failed to initialize before,
463  * reasons being missing parent node(s) during earlier init. This
464  * typically happens only for DPLLs which need to have both of their
465  * parent clocks ready during init.
466  */
467 void ti_dt_clk_init_retry_clks(void)
468 {
469         struct clk_init_item *retry;
470         struct clk_init_item *tmp;
471         int retries = 5;
472
473         while (!list_empty(&retry_list) && retries) {
474                 list_for_each_entry_safe(retry, tmp, &retry_list, link) {
475                         pr_debug("retry-init: %pOFn\n", retry->node);
476                         retry->func(retry->user, retry->node);
477                         list_del(&retry->link);
478                         kfree(retry);
479                 }
480                 retries--;
481         }
482 }
483
484 static const struct of_device_id simple_clk_match_table[] __initconst = {
485         { .compatible = "fixed-clock" },
486         { .compatible = "fixed-factor-clock" },
487         { }
488 };
489
490 /**
491  * ti_dt_clk_name - init clock name from first output name or node name
492  * @np: device node
493  *
494  * Use the first clock-output-name for the clock name if found. Fall back
495  * to legacy naming based on node name.
496  */
497 const char *ti_dt_clk_name(struct device_node *np)
498 {
499         const char *name;
500
501         if (!of_property_read_string_index(np, "clock-output-names", 0,
502                                            &name))
503                 return name;
504
505         return np->name;
506 }
507
508 /**
509  * ti_clk_add_aliases - setup clock aliases
510  *
511  * Sets up any missing clock aliases. No return value.
512  */
513 void __init ti_clk_add_aliases(void)
514 {
515         struct device_node *np;
516         struct clk *clk;
517
518         for_each_matching_node(np, simple_clk_match_table) {
519                 struct of_phandle_args clkspec;
520
521                 clkspec.np = np;
522                 clk = of_clk_get_from_provider(&clkspec);
523
524                 ti_clk_add_alias(clk, ti_dt_clk_name(np));
525         }
526 }
527
528 /**
529  * ti_clk_setup_features - setup clock features flags
530  * @features: features definition to use
531  *
532  * Initializes the clock driver features flags based on platform
533  * provided data. No return value.
534  */
535 void __init ti_clk_setup_features(struct ti_clk_features *features)
536 {
537         memcpy(&ti_clk_features, features, sizeof(*features));
538 }
539
540 /**
541  * ti_clk_get_features - get clock driver features flags
542  *
543  * Get TI clock driver features description. Returns a pointer
544  * to the current feature setup.
545  */
546 const struct ti_clk_features *ti_clk_get_features(void)
547 {
548         return &ti_clk_features;
549 }
550
551 /**
552  * omap2_clk_enable_init_clocks - prepare & enable a list of clocks
553  * @clk_names: ptr to an array of strings of clock names to enable
554  * @num_clocks: number of clock names in @clk_names
555  *
556  * Prepare and enable a list of clocks, named by @clk_names.  No
557  * return value. XXX Deprecated; only needed until these clocks are
558  * properly claimed and enabled by the drivers or core code that uses
559  * them.  XXX What code disables & calls clk_put on these clocks?
560  */
561 void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks)
562 {
563         struct clk *init_clk;
564         int i;
565
566         for (i = 0; i < num_clocks; i++) {
567                 init_clk = clk_get(NULL, clk_names[i]);
568                 if (WARN(IS_ERR(init_clk), "could not find init clock %s\n",
569                          clk_names[i]))
570                         continue;
571                 clk_prepare_enable(init_clk);
572         }
573 }
574
575 /**
576  * ti_clk_add_alias - add a clock alias for a TI clock
577  * @clk: clock handle to create alias for
578  * @con: connection ID for this clock
579  *
580  * Creates a clock alias for a TI clock. Allocates the clock lookup entry
581  * and assigns the data to it. Returns 0 if successful, negative error
582  * value otherwise.
583  */
584 int ti_clk_add_alias(struct clk *clk, const char *con)
585 {
586         struct clk_lookup *cl;
587
588         if (!clk)
589                 return 0;
590
591         if (IS_ERR(clk))
592                 return PTR_ERR(clk);
593
594         cl = kzalloc(sizeof(*cl), GFP_KERNEL);
595         if (!cl)
596                 return -ENOMEM;
597
598         cl->con_id = con;
599         cl->clk = clk;
600
601         clkdev_add(cl);
602
603         return 0;
604 }
605
606 /**
607  * of_ti_clk_register - register a TI clock to the common clock framework
608  * @node: device node for this clock
609  * @hw: hardware clock handle
610  * @con: connection ID for this clock
611  *
612  * Registers a TI clock to the common clock framework, and adds a clock
613  * alias for it. Returns a handle to the registered clock if successful,
614  * ERR_PTR value in failure.
615  */
616 struct clk *of_ti_clk_register(struct device_node *node, struct clk_hw *hw,
617                                const char *con)
618 {
619         struct clk *clk;
620         int ret;
621
622         ret = of_clk_hw_register(node, hw);
623         if (ret)
624                 return ERR_PTR(ret);
625
626         clk = hw->clk;
627         ret = ti_clk_add_alias(clk, con);
628         if (ret) {
629                 clk_unregister(clk);
630                 return ERR_PTR(ret);
631         }
632
633         return clk;
634 }
635
636 /**
637  * of_ti_clk_register_omap_hw - register a clk_hw_omap to the clock framework
638  * @node: device node for this clock
639  * @hw: hardware clock handle
640  * @con: connection ID for this clock
641  *
642  * Registers a clk_hw_omap clock to the clock framewor, adds a clock alias
643  * for it, and adds the list to the available clk_hw_omap type clocks.
644  * Returns a handle to the registered clock if successful, ERR_PTR value
645  * in failure.
646  */
647 struct clk *of_ti_clk_register_omap_hw(struct device_node *node,
648                                        struct clk_hw *hw, const char *con)
649 {
650         struct clk *clk;
651         struct clk_hw_omap *oclk;
652
653         clk = of_ti_clk_register(node, hw, con);
654         if (IS_ERR(clk))
655                 return clk;
656
657         oclk = to_clk_hw_omap(hw);
658
659         list_add(&oclk->node, &clk_hw_omap_clocks);
660
661         return clk;
662 }
663
664 /**
665  * omap2_clk_for_each - call function for each registered clk_hw_omap
666  * @fn: pointer to a callback function
667  *
668  * Call @fn for each registered clk_hw_omap, passing @hw to each
669  * function.  @fn must return 0 for success or any other value for
670  * failure.  If @fn returns non-zero, the iteration across clocks
671  * will stop and the non-zero return value will be passed to the
672  * caller of omap2_clk_for_each().
673  */
674 int omap2_clk_for_each(int (*fn)(struct clk_hw_omap *hw))
675 {
676         int ret;
677         struct clk_hw_omap *hw;
678
679         list_for_each_entry(hw, &clk_hw_omap_clocks, node) {
680                 ret = (*fn)(hw);
681                 if (ret)
682                         break;
683         }
684
685         return ret;
686 }
687
688 /**
689  * omap2_clk_is_hw_omap - check if the provided clk_hw is OMAP clock
690  * @hw: clk_hw to check if it is an omap clock or not
691  *
692  * Checks if the provided clk_hw is OMAP clock or not. Returns true if
693  * it is, false otherwise.
694  */
695 bool omap2_clk_is_hw_omap(struct clk_hw *hw)
696 {
697         struct clk_hw_omap *oclk;
698
699         list_for_each_entry(oclk, &clk_hw_omap_clocks, node) {
700                 if (&oclk->hw == hw)
701                         return true;
702         }
703
704         return false;
705 }
This page took 0.073304 seconds and 4 git commands to generate.