2 * Copyright (c) 2014 MundoReader S.L.
3 * Author: Heiko Stuebner <heiko@sntech.de>
5 * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
6 * Author: Xing Zheng <zhengxing@rock-chips.com>
11 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
12 * Copyright (c) 2013 Linaro Ltd.
13 * Author: Thomas Abraham <thomas.ab@samsung.com>
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
26 #include <linux/slab.h>
27 #include <linux/clk.h>
28 #include <linux/clk-provider.h>
29 #include <linux/mfd/syscon.h>
30 #include <linux/regmap.h>
31 #include <linux/reboot.h>
35 * Register a clock branch.
36 * Most clock branches have a form like
42 * sometimes without one of those components.
44 static struct clk
*rockchip_clk_register_branch(const char *name
,
45 const char *const *parent_names
, u8 num_parents
,
47 int muxdiv_offset
, u8 mux_shift
, u8 mux_width
, u8 mux_flags
,
48 u8 div_shift
, u8 div_width
, u8 div_flags
,
49 struct clk_div_table
*div_table
, int gate_offset
,
50 u8 gate_shift
, u8 gate_flags
, unsigned long flags
,
54 struct clk_mux
*mux
= NULL
;
55 struct clk_gate
*gate
= NULL
;
56 struct clk_divider
*div
= NULL
;
57 const struct clk_ops
*mux_ops
= NULL
, *div_ops
= NULL
,
60 if (num_parents
> 1) {
61 mux
= kzalloc(sizeof(*mux
), GFP_KERNEL
);
63 return ERR_PTR(-ENOMEM
);
65 mux
->reg
= base
+ muxdiv_offset
;
66 mux
->shift
= mux_shift
;
67 mux
->mask
= BIT(mux_width
) - 1;
68 mux
->flags
= mux_flags
;
70 mux_ops
= (mux_flags
& CLK_MUX_READ_ONLY
) ? &clk_mux_ro_ops
74 if (gate_offset
>= 0) {
75 gate
= kzalloc(sizeof(*gate
), GFP_KERNEL
);
79 gate
->flags
= gate_flags
;
80 gate
->reg
= base
+ gate_offset
;
81 gate
->bit_idx
= gate_shift
;
83 gate_ops
= &clk_gate_ops
;
87 div
= kzalloc(sizeof(*div
), GFP_KERNEL
);
91 div
->flags
= div_flags
;
92 div
->reg
= base
+ muxdiv_offset
;
93 div
->shift
= div_shift
;
94 div
->width
= div_width
;
96 div
->table
= div_table
;
97 div_ops
= (div_flags
& CLK_DIVIDER_READ_ONLY
)
102 clk
= clk_register_composite(NULL
, name
, parent_names
, num_parents
,
103 mux
? &mux
->hw
: NULL
, mux_ops
,
104 div
? &div
->hw
: NULL
, div_ops
,
105 gate
? &gate
->hw
: NULL
, gate_ops
,
113 return ERR_PTR(-ENOMEM
);
116 struct rockchip_clk_frac
{
117 struct notifier_block clk_nb
;
118 struct clk_fractional_divider div
;
119 struct clk_gate gate
;
122 const struct clk_ops
*mux_ops
;
125 bool rate_change_remuxed
;
129 #define to_rockchip_clk_frac_nb(nb) \
130 container_of(nb, struct rockchip_clk_frac, clk_nb)
132 static int rockchip_clk_frac_notifier_cb(struct notifier_block
*nb
,
133 unsigned long event
, void *data
)
135 struct clk_notifier_data
*ndata
= data
;
136 struct rockchip_clk_frac
*frac
= to_rockchip_clk_frac_nb(nb
);
137 struct clk_mux
*frac_mux
= &frac
->mux
;
140 pr_debug("%s: event %lu, old_rate %lu, new_rate: %lu\n",
141 __func__
, event
, ndata
->old_rate
, ndata
->new_rate
);
142 if (event
== PRE_RATE_CHANGE
) {
143 frac
->rate_change_idx
=
144 frac
->mux_ops
->get_parent(&frac_mux
->hw
);
145 if (frac
->rate_change_idx
!= frac
->mux_frac_idx
) {
146 frac
->mux_ops
->set_parent(&frac_mux
->hw
,
148 frac
->rate_change_remuxed
= 1;
150 } else if (event
== POST_RATE_CHANGE
) {
152 * The POST_RATE_CHANGE notifier runs directly after the
153 * divider clock is set in clk_change_rate, so we'll have
154 * remuxed back to the original parent before clk_change_rate
155 * reaches the mux itself.
157 if (frac
->rate_change_remuxed
) {
158 frac
->mux_ops
->set_parent(&frac_mux
->hw
,
159 frac
->rate_change_idx
);
160 frac
->rate_change_remuxed
= 0;
164 return notifier_from_errno(ret
);
167 static struct clk
*rockchip_clk_register_frac_branch(
168 struct rockchip_clk_provider
*ctx
, const char *name
,
169 const char *const *parent_names
, u8 num_parents
,
170 void __iomem
*base
, int muxdiv_offset
, u8 div_flags
,
171 int gate_offset
, u8 gate_shift
, u8 gate_flags
,
172 unsigned long flags
, struct rockchip_clk_branch
*child
,
175 struct rockchip_clk_frac
*frac
;
177 struct clk_gate
*gate
= NULL
;
178 struct clk_fractional_divider
*div
= NULL
;
179 const struct clk_ops
*div_ops
= NULL
, *gate_ops
= NULL
;
181 if (muxdiv_offset
< 0)
182 return ERR_PTR(-EINVAL
);
184 if (child
&& child
->branch_type
!= branch_mux
) {
185 pr_err("%s: fractional child clock for %s can only be a mux\n",
187 return ERR_PTR(-EINVAL
);
190 frac
= kzalloc(sizeof(*frac
), GFP_KERNEL
);
192 return ERR_PTR(-ENOMEM
);
194 if (gate_offset
>= 0) {
196 gate
->flags
= gate_flags
;
197 gate
->reg
= base
+ gate_offset
;
198 gate
->bit_idx
= gate_shift
;
200 gate_ops
= &clk_gate_ops
;
204 div
->flags
= div_flags
;
205 div
->reg
= base
+ muxdiv_offset
;
208 div
->mmask
= GENMASK(div
->mwidth
- 1, 0) << div
->mshift
;
211 div
->nmask
= GENMASK(div
->nwidth
- 1, 0) << div
->nshift
;
213 div_ops
= &clk_fractional_divider_ops
;
215 clk
= clk_register_composite(NULL
, name
, parent_names
, num_parents
,
218 gate
? &gate
->hw
: NULL
, gate_ops
,
219 flags
| CLK_SET_RATE_UNGATE
);
226 struct clk_mux
*frac_mux
= &frac
->mux
;
227 struct clk_init_data init
;
231 frac
->mux_frac_idx
= -1;
232 for (i
= 0; i
< child
->num_parents
; i
++) {
233 if (!strcmp(name
, child
->parent_names
[i
])) {
234 pr_debug("%s: found fractional parent in mux at pos %d\n",
236 frac
->mux_frac_idx
= i
;
241 frac
->mux_ops
= &clk_mux_ops
;
242 frac
->clk_nb
.notifier_call
= rockchip_clk_frac_notifier_cb
;
244 frac_mux
->reg
= base
+ child
->muxdiv_offset
;
245 frac_mux
->shift
= child
->mux_shift
;
246 frac_mux
->mask
= BIT(child
->mux_width
) - 1;
247 frac_mux
->flags
= child
->mux_flags
;
248 frac_mux
->lock
= lock
;
249 frac_mux
->hw
.init
= &init
;
251 init
.name
= child
->name
;
252 init
.flags
= child
->flags
| CLK_SET_RATE_PARENT
;
253 init
.ops
= frac
->mux_ops
;
254 init
.parent_names
= child
->parent_names
;
255 init
.num_parents
= child
->num_parents
;
257 mux_clk
= clk_register(NULL
, &frac_mux
->hw
);
261 rockchip_clk_add_lookup(ctx
, mux_clk
, child
->id
);
263 /* notifier on the fraction divider to catch rate changes */
264 if (frac
->mux_frac_idx
>= 0) {
265 ret
= clk_notifier_register(clk
, &frac
->clk_nb
);
267 pr_err("%s: failed to register clock notifier for %s\n",
270 pr_warn("%s: could not find %s as parent of %s, rate changes may not work\n",
271 __func__
, name
, child
->name
);
278 static struct clk
*rockchip_clk_register_factor_branch(const char *name
,
279 const char *const *parent_names
, u8 num_parents
,
280 void __iomem
*base
, unsigned int mult
, unsigned int div
,
281 int gate_offset
, u8 gate_shift
, u8 gate_flags
,
282 unsigned long flags
, spinlock_t
*lock
)
285 struct clk_gate
*gate
= NULL
;
286 struct clk_fixed_factor
*fix
= NULL
;
288 /* without gate, register a simple factor clock */
289 if (gate_offset
== 0) {
290 return clk_register_fixed_factor(NULL
, name
,
291 parent_names
[0], flags
, mult
,
295 gate
= kzalloc(sizeof(*gate
), GFP_KERNEL
);
297 return ERR_PTR(-ENOMEM
);
299 gate
->flags
= gate_flags
;
300 gate
->reg
= base
+ gate_offset
;
301 gate
->bit_idx
= gate_shift
;
304 fix
= kzalloc(sizeof(*fix
), GFP_KERNEL
);
307 return ERR_PTR(-ENOMEM
);
313 clk
= clk_register_composite(NULL
, name
, parent_names
, num_parents
,
315 &fix
->hw
, &clk_fixed_factor_ops
,
316 &gate
->hw
, &clk_gate_ops
, flags
);
325 struct rockchip_clk_provider
* __init
rockchip_clk_init(struct device_node
*np
,
326 void __iomem
*base
, unsigned long nr_clks
)
328 struct rockchip_clk_provider
*ctx
;
329 struct clk
**clk_table
;
332 ctx
= kzalloc(sizeof(struct rockchip_clk_provider
), GFP_KERNEL
);
334 return ERR_PTR(-ENOMEM
);
336 clk_table
= kcalloc(nr_clks
, sizeof(struct clk
*), GFP_KERNEL
);
340 for (i
= 0; i
< nr_clks
; ++i
)
341 clk_table
[i
] = ERR_PTR(-ENOENT
);
343 ctx
->reg_base
= base
;
344 ctx
->clk_data
.clks
= clk_table
;
345 ctx
->clk_data
.clk_num
= nr_clks
;
347 ctx
->grf
= ERR_PTR(-EPROBE_DEFER
);
348 spin_lock_init(&ctx
->lock
);
350 ctx
->grf
= syscon_regmap_lookup_by_phandle(ctx
->cru_node
,
357 return ERR_PTR(-ENOMEM
);
360 void __init
rockchip_clk_of_add_provider(struct device_node
*np
,
361 struct rockchip_clk_provider
*ctx
)
363 if (of_clk_add_provider(np
, of_clk_src_onecell_get
,
365 pr_err("%s: could not register clk provider\n", __func__
);
368 void rockchip_clk_add_lookup(struct rockchip_clk_provider
*ctx
,
369 struct clk
*clk
, unsigned int id
)
371 if (ctx
->clk_data
.clks
&& id
)
372 ctx
->clk_data
.clks
[id
] = clk
;
375 void __init
rockchip_clk_register_plls(struct rockchip_clk_provider
*ctx
,
376 struct rockchip_pll_clock
*list
,
377 unsigned int nr_pll
, int grf_lock_offset
)
382 for (idx
= 0; idx
< nr_pll
; idx
++, list
++) {
383 clk
= rockchip_clk_register_pll(ctx
, list
->type
, list
->name
,
384 list
->parent_names
, list
->num_parents
,
385 list
->con_offset
, grf_lock_offset
,
386 list
->lock_shift
, list
->mode_offset
,
387 list
->mode_shift
, list
->rate_table
,
388 list
->flags
, list
->pll_flags
);
390 pr_err("%s: failed to register clock %s\n", __func__
,
395 rockchip_clk_add_lookup(ctx
, clk
, list
->id
);
399 void __init
rockchip_clk_register_branches(
400 struct rockchip_clk_provider
*ctx
,
401 struct rockchip_clk_branch
*list
,
404 struct clk
*clk
= NULL
;
408 for (idx
= 0; idx
< nr_clk
; idx
++, list
++) {
411 /* catch simple muxes */
412 switch (list
->branch_type
) {
414 clk
= clk_register_mux(NULL
, list
->name
,
415 list
->parent_names
, list
->num_parents
,
416 flags
, ctx
->reg_base
+ list
->muxdiv_offset
,
417 list
->mux_shift
, list
->mux_width
,
418 list
->mux_flags
, &ctx
->lock
);
422 clk
= clk_register_divider_table(NULL
,
423 list
->name
, list
->parent_names
[0],
425 ctx
->reg_base
+ list
->muxdiv_offset
,
426 list
->div_shift
, list
->div_width
,
427 list
->div_flags
, list
->div_table
,
430 clk
= clk_register_divider(NULL
, list
->name
,
431 list
->parent_names
[0], flags
,
432 ctx
->reg_base
+ list
->muxdiv_offset
,
433 list
->div_shift
, list
->div_width
,
434 list
->div_flags
, &ctx
->lock
);
436 case branch_fraction_divider
:
437 clk
= rockchip_clk_register_frac_branch(ctx
, list
->name
,
438 list
->parent_names
, list
->num_parents
,
439 ctx
->reg_base
, list
->muxdiv_offset
,
441 list
->gate_offset
, list
->gate_shift
,
442 list
->gate_flags
, flags
, list
->child
,
446 flags
|= CLK_SET_RATE_PARENT
;
448 clk
= clk_register_gate(NULL
, list
->name
,
449 list
->parent_names
[0], flags
,
450 ctx
->reg_base
+ list
->gate_offset
,
451 list
->gate_shift
, list
->gate_flags
, &ctx
->lock
);
453 case branch_composite
:
454 clk
= rockchip_clk_register_branch(list
->name
,
455 list
->parent_names
, list
->num_parents
,
456 ctx
->reg_base
, list
->muxdiv_offset
,
458 list
->mux_width
, list
->mux_flags
,
459 list
->div_shift
, list
->div_width
,
460 list
->div_flags
, list
->div_table
,
461 list
->gate_offset
, list
->gate_shift
,
462 list
->gate_flags
, flags
, &ctx
->lock
);
465 clk
= rockchip_clk_register_mmc(
467 list
->parent_names
, list
->num_parents
,
468 ctx
->reg_base
+ list
->muxdiv_offset
,
472 case branch_inverter
:
473 clk
= rockchip_clk_register_inverter(
474 list
->name
, list
->parent_names
,
476 ctx
->reg_base
+ list
->muxdiv_offset
,
477 list
->div_shift
, list
->div_flags
, &ctx
->lock
);
480 clk
= rockchip_clk_register_factor_branch(
481 list
->name
, list
->parent_names
,
482 list
->num_parents
, ctx
->reg_base
,
483 list
->div_shift
, list
->div_width
,
484 list
->gate_offset
, list
->gate_shift
,
485 list
->gate_flags
, flags
, &ctx
->lock
);
488 clk
= rockchip_clk_register_ddrclk(
489 list
->name
, list
->flags
,
490 list
->parent_names
, list
->num_parents
,
491 list
->muxdiv_offset
, list
->mux_shift
,
492 list
->mux_width
, list
->div_shift
,
493 list
->div_width
, list
->div_flags
,
494 ctx
->reg_base
, &ctx
->lock
);
498 /* none of the cases above matched */
500 pr_err("%s: unknown clock type %d\n",
501 __func__
, list
->branch_type
);
506 pr_err("%s: failed to register clock %s: %ld\n",
507 __func__
, list
->name
, PTR_ERR(clk
));
511 rockchip_clk_add_lookup(ctx
, clk
, list
->id
);
515 void __init
rockchip_clk_register_armclk(struct rockchip_clk_provider
*ctx
,
516 unsigned int lookup_id
,
517 const char *name
, const char *const *parent_names
,
519 const struct rockchip_cpuclk_reg_data
*reg_data
,
520 const struct rockchip_cpuclk_rate_table
*rates
,
525 clk
= rockchip_clk_register_cpuclk(name
, parent_names
, num_parents
,
526 reg_data
, rates
, nrates
,
527 ctx
->reg_base
, &ctx
->lock
);
529 pr_err("%s: failed to register clock %s: %ld\n",
530 __func__
, name
, PTR_ERR(clk
));
534 rockchip_clk_add_lookup(ctx
, clk
, lookup_id
);
537 void __init
rockchip_clk_protect_critical(const char *const clocks
[],
542 /* Protect the clocks that needs to stay on */
543 for (i
= 0; i
< nclocks
; i
++) {
544 struct clk
*clk
= __clk_lookup(clocks
[i
]);
547 clk_prepare_enable(clk
);
551 static void __iomem
*rst_base
;
552 static unsigned int reg_restart
;
553 static void (*cb_restart
)(void);
554 static int rockchip_restart_notify(struct notifier_block
*this,
555 unsigned long mode
, void *cmd
)
560 writel(0xfdb9, rst_base
+ reg_restart
);
564 static struct notifier_block rockchip_restart_handler
= {
565 .notifier_call
= rockchip_restart_notify
,
570 rockchip_register_restart_notifier(struct rockchip_clk_provider
*ctx
,
576 rst_base
= ctx
->reg_base
;
579 ret
= register_restart_handler(&rockchip_restart_handler
);
581 pr_err("%s: cannot register restart handler, %d\n",