Lines Matching +full:parent +full:- +full:clk
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * arch/arm/mach-ep93xx/clock.c
12 #include <linux/clk.h>
27 struct clk { struct
28 struct clk *parent; member
35 unsigned long (*get_rate)(struct clk *clk); argument
36 int (*set_rate)(struct clk *clk, unsigned long rate); argument
40 static unsigned long get_uart_rate(struct clk *clk);
42 static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
43 static int set_div_rate(struct clk *clk, unsigned long rate);
44 static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate);
45 static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate);
47 static struct clk clk_xtali = {
50 static struct clk clk_uart1 = {
51 .parent = &clk_xtali,
57 static struct clk clk_uart2 = {
58 .parent = &clk_xtali,
64 static struct clk clk_uart3 = {
65 .parent = &clk_xtali,
71 static struct clk clk_pll1 = {
72 .parent = &clk_xtali,
74 static struct clk clk_f = {
75 .parent = &clk_pll1,
77 static struct clk clk_h = {
78 .parent = &clk_pll1,
80 static struct clk clk_p = {
81 .parent = &clk_pll1,
83 static struct clk clk_pll2 = {
84 .parent = &clk_xtali,
86 static struct clk clk_usb_host = {
87 .parent = &clk_pll2,
91 static struct clk clk_keypad = {
92 .parent = &clk_xtali,
98 static struct clk clk_adc = {
99 .parent = &clk_xtali,
105 static struct clk clk_spi = {
106 .parent = &clk_xtali,
109 static struct clk clk_pwm = {
110 .parent = &clk_xtali,
114 static struct clk clk_video = {
121 static struct clk clk_i2s_mclk = {
128 static struct clk clk_i2s_sclk = {
130 .parent = &clk_i2s_mclk,
136 static struct clk clk_i2s_lrclk = {
138 .parent = &clk_i2s_sclk,
145 static struct clk clk_m2p0 = {
146 .parent = &clk_h,
150 static struct clk clk_m2p1 = {
151 .parent = &clk_h,
155 static struct clk clk_m2p2 = {
156 .parent = &clk_h,
160 static struct clk clk_m2p3 = {
161 .parent = &clk_h,
165 static struct clk clk_m2p4 = {
166 .parent = &clk_h,
170 static struct clk clk_m2p5 = {
171 .parent = &clk_h,
175 static struct clk clk_m2p6 = {
176 .parent = &clk_h,
180 static struct clk clk_m2p7 = {
181 .parent = &clk_h,
185 static struct clk clk_m2p8 = {
186 .parent = &clk_h,
190 static struct clk clk_m2p9 = {
191 .parent = &clk_h,
195 static struct clk clk_m2m0 = {
196 .parent = &clk_h,
200 static struct clk clk_m2m1 = {
201 .parent = &clk_h,
207 { .dev_id = dev, .con_id = con, .clk = ck }
219 INIT_CK("ohci-platform", NULL, &clk_usb_host),
220 INIT_CK("ep93xx-keypad", NULL, &clk_keypad),
221 INIT_CK("ep93xx-adc", NULL, &clk_adc),
222 INIT_CK("ep93xx-fb", NULL, &clk_video),
223 INIT_CK("ep93xx-spi.0", NULL, &clk_spi),
224 INIT_CK("ep93xx-i2s", "mclk", &clk_i2s_mclk),
225 INIT_CK("ep93xx-i2s", "sclk", &clk_i2s_sclk),
226 INIT_CK("ep93xx-i2s", "lrclk", &clk_i2s_lrclk),
244 static void __clk_enable(struct clk *clk) in __clk_enable() argument
246 if (!clk->users++) { in __clk_enable()
247 if (clk->parent) in __clk_enable()
248 __clk_enable(clk->parent); in __clk_enable()
250 if (clk->enable_reg) { in __clk_enable()
253 v = __raw_readl(clk->enable_reg); in __clk_enable()
254 v |= clk->enable_mask; in __clk_enable()
255 if (clk->sw_locked) in __clk_enable()
256 ep93xx_syscon_swlocked_write(v, clk->enable_reg); in __clk_enable()
258 __raw_writel(v, clk->enable_reg); in __clk_enable()
263 int clk_enable(struct clk *clk) in clk_enable() argument
267 if (!clk) in clk_enable()
268 return -EINVAL; in clk_enable()
271 __clk_enable(clk); in clk_enable()
278 static void __clk_disable(struct clk *clk) in __clk_disable() argument
280 if (!--clk->users) { in __clk_disable()
281 if (clk->enable_reg) { in __clk_disable()
284 v = __raw_readl(clk->enable_reg); in __clk_disable()
285 v &= ~clk->enable_mask; in __clk_disable()
286 if (clk->sw_locked) in __clk_disable()
287 ep93xx_syscon_swlocked_write(v, clk->enable_reg); in __clk_disable()
289 __raw_writel(v, clk->enable_reg); in __clk_disable()
292 if (clk->parent) in __clk_disable()
293 __clk_disable(clk->parent); in __clk_disable()
297 void clk_disable(struct clk *clk) in clk_disable() argument
301 if (!clk) in clk_disable()
305 __clk_disable(clk); in clk_disable()
310 static unsigned long get_uart_rate(struct clk *clk) in get_uart_rate() argument
312 unsigned long rate = clk_get_rate(clk->parent); in get_uart_rate()
322 unsigned long clk_get_rate(struct clk *clk) in clk_get_rate() argument
324 if (clk->get_rate) in clk_get_rate()
325 return clk->get_rate(clk); in clk_get_rate()
327 return clk->rate; in clk_get_rate()
331 static int set_keytchclk_rate(struct clk *clk, unsigned long rate) in set_keytchclk_rate() argument
336 val = __raw_readl(clk->enable_reg); in set_keytchclk_rate()
345 div_bit = clk->enable_mask >> 15; in set_keytchclk_rate()
352 return -EINVAL; in set_keytchclk_rate()
354 ep93xx_syscon_swlocked_write(val, clk->enable_reg); in set_keytchclk_rate()
355 clk->rate = rate; in set_keytchclk_rate()
359 static int calc_clk_div(struct clk *clk, unsigned long rate, in calc_clk_div() argument
362 struct clk *mclk; in calc_clk_div()
363 unsigned long max_rate, actual_rate, mclk_rate, rate_err = -1; in calc_clk_div()
376 * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf in calc_clk_div()
386 mclk_rate = mclk->rate * 2; in calc_clk_div()
396 if (!found || abs(actual_rate - rate) < rate_err) { in calc_clk_div()
397 *pdiv = __pdiv - 3; in calc_clk_div()
401 clk->parent = mclk; in calc_clk_div()
402 clk->rate = actual_rate; in calc_clk_div()
403 rate_err = abs(actual_rate - rate); in calc_clk_div()
410 return -EINVAL; in calc_clk_div()
415 static int set_div_rate(struct clk *clk, unsigned long rate) in set_div_rate() argument
420 err = calc_clk_div(clk, rate, &psel, &esel, &pdiv, &div); in set_div_rate()
425 val = __raw_readl(clk->enable_reg); in set_div_rate()
432 ep93xx_syscon_swlocked_write(val, clk->enable_reg); in set_div_rate()
436 static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate) in set_i2s_sclk_rate() argument
438 unsigned val = __raw_readl(clk->enable_reg); in set_i2s_sclk_rate()
442 clk->enable_reg); in set_i2s_sclk_rate()
445 clk->enable_reg); in set_i2s_sclk_rate()
447 return -EINVAL; in set_i2s_sclk_rate()
453 static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate) in set_i2s_lrclk_rate() argument
455 unsigned val = __raw_readl(clk->enable_reg) & in set_i2s_lrclk_rate()
460 clk->enable_reg); in set_i2s_lrclk_rate()
463 clk->enable_reg); in set_i2s_lrclk_rate()
466 clk->enable_reg); in set_i2s_lrclk_rate()
468 return -EINVAL; in set_i2s_lrclk_rate()
474 int clk_set_rate(struct clk *clk, unsigned long rate) in clk_set_rate() argument
476 if (clk->set_rate) in clk_set_rate()
477 return clk->set_rate(clk, rate); in clk_set_rate()
479 return -EINVAL; in clk_set_rate()
483 long clk_round_rate(struct clk *clk, unsigned long rate) in clk_round_rate() argument
485 WARN_ON(clk); in clk_round_rate()
490 int clk_set_parent(struct clk *clk, struct clk *parent) in clk_set_parent() argument
492 WARN_ON(clk); in clk_set_parent()
497 struct clk *clk_get_parent(struct clk *clk) in clk_get_parent() argument
499 return clk->parent; in clk_get_parent()