Lines Matching refs:clk
21 static SLIST_HEAD(, clk) clock_list = SLIST_HEAD_INITIALIZER(clock_list);
34 struct clk *clk_alloc(const char *name, const struct clk_ops *ops, in clk_alloc()
35 struct clk **parent_clks, size_t parent_count) in clk_alloc()
37 struct clk *clk = NULL; in clk_alloc() local
40 clk = calloc(1, sizeof(*clk) + parent_count * sizeof(clk)); in clk_alloc()
41 if (!clk) in clk_alloc()
44 clk->num_parents = parent_count; in clk_alloc()
46 clk->parents[parent] = parent_clks[parent]; in clk_alloc()
48 clk->name = name; in clk_alloc()
49 clk->ops = ops; in clk_alloc()
50 refcount_set(&clk->enabled_count, 0); in clk_alloc()
52 return clk; in clk_alloc()
55 void clk_free(struct clk *clk) in clk_free() argument
57 free(clk); in clk_free()
60 static bool __maybe_unused clk_check(struct clk *clk) in clk_check() argument
62 if (!clk || !clk->ops) in clk_check()
65 if (clk->ops->set_parent && !clk->ops->get_parent) in clk_check()
68 if (clk->num_parents > 1 && !clk->ops->get_parent) in clk_check()
74 static void clk_compute_rate_no_lock(struct clk *clk) in clk_compute_rate_no_lock() argument
78 if (clk->parent) { in clk_compute_rate_no_lock()
79 clk_compute_rate_no_lock(clk->parent); in clk_compute_rate_no_lock()
80 parent_rate = clk->parent->rate; in clk_compute_rate_no_lock()
83 if (clk->ops->get_rate) in clk_compute_rate_no_lock()
84 clk->rate = clk->ops->get_rate(clk, parent_rate); in clk_compute_rate_no_lock()
86 clk->rate = parent_rate; in clk_compute_rate_no_lock()
89 struct clk *clk_get_parent_by_index(struct clk *clk, size_t pidx) in clk_get_parent_by_index() argument
91 if (pidx >= clk->num_parents) in clk_get_parent_by_index()
94 return clk->parents[pidx]; in clk_get_parent_by_index()
97 static void clk_init_parent(struct clk *clk) in clk_init_parent() argument
101 switch (clk->num_parents) { in clk_init_parent()
105 clk->parent = clk->parents[0]; in clk_init_parent()
108 pidx = clk->ops->get_parent(clk); in clk_init_parent()
109 assert(pidx < clk->num_parents); in clk_init_parent()
111 clk->parent = clk->parents[pidx]; in clk_init_parent()
116 TEE_Result clk_register(struct clk *clk) in clk_register() argument
118 assert(clk_check(clk)); in clk_register()
120 clk_init_parent(clk); in clk_register()
121 clk_compute_rate_no_lock(clk); in clk_register()
124 SLIST_INSERT_HEAD(&clock_list, clk, link); in clk_register()
127 DMSG("Registered clock %s, freq %lu", clk->name, clk_get_rate(clk)); in clk_register()
132 static bool clk_is_enabled_no_lock(struct clk *clk) in clk_is_enabled_no_lock() argument
134 return refcount_val(&clk->enabled_count) != 0; in clk_is_enabled_no_lock()
137 bool clk_is_enabled(struct clk *clk) in clk_is_enabled() argument
139 return clk_is_enabled_no_lock(clk); in clk_is_enabled()
142 static void clk_disable_no_lock(struct clk *clk) in clk_disable_no_lock() argument
144 struct clk *parent = NULL; in clk_disable_no_lock()
146 if (!refcount_dec(&clk->enabled_count)) in clk_disable_no_lock()
149 if (clk->ops->disable) in clk_disable_no_lock()
150 clk->ops->disable(clk); in clk_disable_no_lock()
152 parent = clk_get_parent(clk); in clk_disable_no_lock()
157 static TEE_Result clk_enable_no_lock(struct clk *clk) in clk_enable_no_lock() argument
160 struct clk *parent = NULL; in clk_enable_no_lock()
162 if (refcount_inc(&clk->enabled_count)) in clk_enable_no_lock()
165 parent = clk_get_parent(clk); in clk_enable_no_lock()
172 if (clk->ops->enable) { in clk_enable_no_lock()
173 res = clk->ops->enable(clk); in clk_enable_no_lock()
182 refcount_set(&clk->enabled_count, 1); in clk_enable_no_lock()
187 TEE_Result clk_enable(struct clk *clk) in clk_enable() argument
192 res = clk_enable_no_lock(clk); in clk_enable()
198 void clk_disable(struct clk *clk) in clk_disable() argument
201 clk_disable_no_lock(clk); in clk_disable()
205 unsigned long clk_get_rate(struct clk *clk) in clk_get_rate() argument
207 clk_compute_rate_no_lock(clk); in clk_get_rate()
209 return clk->rate; in clk_get_rate()
212 static TEE_Result clk_set_rate_no_lock(struct clk *clk, unsigned long rate) in clk_set_rate_no_lock() argument
217 if (clk->parent) in clk_set_rate_no_lock()
218 parent_rate = clk_get_rate(clk->parent); in clk_set_rate_no_lock()
220 assert(!(clk->flags & CLK_SET_RATE_PARENT) || clk->parent); in clk_set_rate_no_lock()
221 if (clk->flags & CLK_SET_RATE_PARENT) { in clk_set_rate_no_lock()
222 res = clk_set_rate_no_lock(clk->parent, rate); in clk_set_rate_no_lock()
225 rate = clk_get_rate(clk->parent); in clk_set_rate_no_lock()
228 if (clk->ops->set_rate) { in clk_set_rate_no_lock()
229 if (clk->flags & CLK_SET_RATE_UNGATE) { in clk_set_rate_no_lock()
230 res = clk_enable_no_lock(clk); in clk_set_rate_no_lock()
235 res = clk->ops->set_rate(clk, rate, parent_rate); in clk_set_rate_no_lock()
237 if (clk->flags & CLK_SET_RATE_UNGATE) in clk_set_rate_no_lock()
238 clk_disable_no_lock(clk); in clk_set_rate_no_lock()
244 clk_compute_rate_no_lock(clk); in clk_set_rate_no_lock()
249 TEE_Result clk_set_rate(struct clk *clk, unsigned long rate) in clk_set_rate() argument
255 if (clk->flags & CLK_SET_RATE_GATE && clk_is_enabled_no_lock(clk)) in clk_set_rate()
258 res = clk_set_rate_no_lock(clk, rate); in clk_set_rate()
265 struct clk *clk_get_parent(struct clk *clk) in clk_get_parent() argument
267 return clk->parent; in clk_get_parent()
270 static TEE_Result clk_get_parent_idx(struct clk *clk, struct clk *parent, in clk_get_parent_idx() argument
275 for (i = 0; i < clk_get_num_parents(clk); i++) { in clk_get_parent_idx()
276 if (clk_get_parent_by_index(clk, i) == parent) { in clk_get_parent_idx()
281 EMSG("Clock %s is not a parent of clock %s", parent->name, clk->name); in clk_get_parent_idx()
286 static TEE_Result clk_set_parent_no_lock(struct clk *clk, struct clk *parent, in clk_set_parent_no_lock() argument
293 if (clk->parent == parent) in clk_set_parent_no_lock()
296 was_enabled = clk_is_enabled_no_lock(clk); in clk_set_parent_no_lock()
299 if (clk->flags & CLK_SET_PARENT_PRE_ENABLE) { in clk_set_parent_no_lock()
305 clk_disable_no_lock(clk); in clk_set_parent_no_lock()
308 res = clk->ops->set_parent(clk, pidx); in clk_set_parent_no_lock()
312 clk->parent = parent; in clk_set_parent_no_lock()
315 clk_compute_rate_no_lock(clk); in clk_set_parent_no_lock()
320 res = clk_enable_no_lock(clk); in clk_set_parent_no_lock()
324 if (clk->flags & CLK_SET_PARENT_PRE_ENABLE) { in clk_set_parent_no_lock()
333 TEE_Result clk_set_parent(struct clk *clk, struct clk *parent) in clk_set_parent() argument
338 if (clk_get_parent_idx(clk, parent, &pidx) || !clk->ops->set_parent) in clk_set_parent()
342 if (clk->flags & CLK_SET_PARENT_GATE && clk_is_enabled_no_lock(clk)) { in clk_set_parent()
347 res = clk_set_parent_no_lock(clk, parent, pidx); in clk_set_parent()
354 TEE_Result clk_get_rates_array(struct clk *clk, size_t start_index, in clk_get_rates_array() argument
357 if (!clk->ops->get_rates_array) in clk_get_rates_array()
360 return clk->ops->get_rates_array(clk, start_index, rates, nb_elts); in clk_get_rates_array()
363 TEE_Result clk_get_rates_steps(struct clk *clk, unsigned long *min, in clk_get_rates_steps() argument
366 if (!clk->ops->get_rates_steps) in clk_get_rates_steps()
369 return clk->ops->get_rates_steps(clk, min, max, step); in clk_get_rates_steps()
372 TEE_Result clk_get_duty_cycle(struct clk *clk, in clk_get_duty_cycle() argument
375 if (clk->ops->get_duty_cycle) in clk_get_duty_cycle()
376 return clk->ops->get_duty_cycle(clk, duty_cycle); in clk_get_duty_cycle()
378 if (clk->parent && (clk->flags & CLK_DUTY_CYCLE_PARENT)) in clk_get_duty_cycle()
379 return clk_get_duty_cycle(clk->parent, duty_cycle); in clk_get_duty_cycle()
405 static struct clk *find_next_clk(struct clk *parent __maybe_unused, in find_next_clk()
406 struct clk *sibling __maybe_unused) in find_next_clk()
408 struct clk *clk = NULL; in find_next_clk() local
412 clk = SLIST_NEXT(sibling, link); in find_next_clk()
414 clk = SLIST_FIRST(&clock_list); in find_next_clk()
416 while (clk && clk->parent != parent) in find_next_clk()
417 clk = SLIST_NEXT(clk, link); in find_next_clk()
420 return clk; in find_next_clk()
423 static bool clk_is_parent_last_child(struct clk *clk) in clk_is_parent_last_child() argument
425 return !find_next_clk(clk->parent, clk); in clk_is_parent_last_child()
428 static bool indent_last_node_already_found(struct clk *node_clk, in indent_last_node_already_found()
431 struct clk *clk = node_clk; in indent_last_node_already_found() local
436 clk = clk->parent; in indent_last_node_already_found()
438 return clk_is_parent_last_child(clk); in indent_last_node_already_found()
441 static void __maybe_unused print_clk(struct clk *clk, int indent) in print_clk() argument
465 if (indent_last_node_already_found(clk, indent, n)) in print_clk()
475 if (clk_is_parent_last_child(clk)) in print_clk()
486 rate = clk_get_rate(clk); in print_clk()
491 clk_get_name(clk), in print_clk()
492 refcount_val(&clk->enabled_count) ? "on " : "off", in print_clk()
493 refcount_val(&clk->enabled_count), in print_clk()
507 struct clk *clk = NULL; in print_tree() local
508 struct clk *parent = NULL; in print_tree()
509 struct clk *next = NULL; in print_tree()
520 next = find_next_clk(parent, clk); in print_tree()
526 clk = NULL; in print_tree()
538 clk = parent; in print_tree()
539 parent = clk->parent; in print_tree()