Skip to content

Commit 53fbbc2

Browse files
committed
Merge tag 'v6.19-rockchip-clk1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip into clk-rockchip
Pull Rockchip clk driver updates from Heiko Stuebner: - SCMI clock-ids and max-clk-number removal from dt-binding on RK3568 - Clock drivers for the new Rockchip SoCs RV1126B and RK3506 * tag 'v6.19-rockchip-clk1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip: clk: rockchip: Add clock and reset driver for RK3506 dt-bindings: clock: rockchip: Add RK3506 clock and reset unit clk: rockchip: Add clock controller for the RV1126B dt-bindings: clock, reset: Add support for rv1126b clk: rockchip: Implement rockchip_clk_register_armclk_multi_pll() dt-bindings: clock: rk3568: Drop CLK_NR_CLKS define clk: rockchip: rk3568: Drop CLK_NR_CLKS usage dt-bindings: clock: rk3568: Add SCMI clock ids
2 parents 3a86608 + 18191dd commit 53fbbc2

17 files changed

Lines changed: 4365 additions & 2 deletions

File tree

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Rockchip RK3506 Clock and Reset Unit (CRU)
8+
9+
maintainers:
10+
- Finley Xiao <finley.xiao@rock-chips.com>
11+
- Heiko Stuebner <heiko@sntech.de>
12+
13+
description:
14+
The RK3506 CRU generates the clock and also implements reset for SoC
15+
peripherals.
16+
17+
properties:
18+
compatible:
19+
const: rockchip,rk3506-cru
20+
21+
reg:
22+
maxItems: 1
23+
24+
"#clock-cells":
25+
const: 1
26+
27+
"#reset-cells":
28+
const: 1
29+
30+
clocks:
31+
maxItems: 1
32+
33+
clock-names:
34+
const: xin
35+
36+
required:
37+
- compatible
38+
- reg
39+
- "#clock-cells"
40+
- "#reset-cells"
41+
- clocks
42+
- clock-names
43+
44+
additionalProperties: false
45+
46+
examples:
47+
- |
48+
clock-controller@ff9a0000 {
49+
compatible = "rockchip,rk3506-cru";
50+
reg = <0xff9a0000 0x20000>;
51+
#clock-cells = <1>;
52+
#reset-cells = <1>;
53+
clocks = <&xin24m>;
54+
clock-names = "xin";
55+
};
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/clock/rockchip,rv1126b-cru.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Rockchip RV1126B Clock and Reset Unit
8+
9+
maintainers:
10+
- Elaine Zhang <zhangqing@rock-chips.com>
11+
- Heiko Stuebner <heiko@sntech.de>
12+
13+
description:
14+
The rv1126b clock controller generates the clock and also implements a
15+
reset controller for SoC peripherals.
16+
17+
properties:
18+
compatible:
19+
enum:
20+
- rockchip,rv1126b-cru
21+
22+
reg:
23+
maxItems: 1
24+
25+
"#clock-cells":
26+
const: 1
27+
28+
"#reset-cells":
29+
const: 1
30+
31+
clocks:
32+
maxItems: 1
33+
34+
clock-names:
35+
const: xin24m
36+
37+
required:
38+
- compatible
39+
- reg
40+
- "#clock-cells"
41+
- "#reset-cells"
42+
43+
additionalProperties: false
44+
45+
examples:
46+
- |
47+
clock-controller@20000000 {
48+
compatible = "rockchip,rv1126b-cru";
49+
reg = <0x20000000 0xc0000>;
50+
#clock-cells = <1>;
51+
#reset-cells = <1>;
52+
};

drivers/clk/rockchip/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ config CLK_RV1126
3030
help
3131
Build the driver for RV1126 Clock Driver.
3232

33+
config CLK_RV1126B
34+
bool "Rockchip RV1126B clock controller support"
35+
depends on ARM64 || COMPILE_TEST
36+
default y
37+
help
38+
Build the driver for RV1126B Clock Driver.
39+
3340
config CLK_RK3036
3441
bool "Rockchip RK3036 clock controller support"
3542
depends on ARM || COMPILE_TEST
@@ -93,6 +100,13 @@ config CLK_RK3399
93100
help
94101
Build the driver for RK3399 Clock Driver.
95102

103+
config CLK_RK3506
104+
bool "Rockchip RK3506 clock controller support"
105+
depends on ARM || COMPILE_TEST
106+
default y
107+
help
108+
Build the driver for RK3506 Clock Driver.
109+
96110
config CLK_RK3528
97111
bool "Rockchip RK3528 clock controller support"
98112
depends on ARM64 || COMPILE_TEST

drivers/clk/rockchip/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
2020
obj-$(CONFIG_CLK_PX30) += clk-px30.o
2121
obj-$(CONFIG_CLK_RV110X) += clk-rv1108.o
2222
obj-$(CONFIG_CLK_RV1126) += clk-rv1126.o
23+
obj-$(CONFIG_CLK_RV1126B) += clk-rv1126b.o rst-rv1126b.o
2324
obj-$(CONFIG_CLK_RK3036) += clk-rk3036.o
2425
obj-$(CONFIG_CLK_RK312X) += clk-rk3128.o
2526
obj-$(CONFIG_CLK_RK3188) += clk-rk3188.o
@@ -29,6 +30,7 @@ obj-$(CONFIG_CLK_RK3308) += clk-rk3308.o
2930
obj-$(CONFIG_CLK_RK3328) += clk-rk3328.o
3031
obj-$(CONFIG_CLK_RK3368) += clk-rk3368.o
3132
obj-$(CONFIG_CLK_RK3399) += clk-rk3399.o
33+
obj-$(CONFIG_CLK_RK3506) += clk-rk3506.o rst-rk3506.o
3234
obj-$(CONFIG_CLK_RK3528) += clk-rk3528.o rst-rk3528.o
3335
obj-$(CONFIG_CLK_RK3562) += clk-rk3562.o rst-rk3562.o
3436
obj-$(CONFIG_CLK_RK3568) += clk-rk3568.o

drivers/clk/rockchip/clk-cpu.c

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,3 +396,168 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
396396
kfree(cpuclk);
397397
return ERR_PTR(ret);
398398
}
399+
400+
static int rockchip_cpuclk_multi_pll_pre_rate_change(struct rockchip_cpuclk *cpuclk,
401+
struct clk_notifier_data *ndata)
402+
{
403+
unsigned long new_rate = roundup(ndata->new_rate, 1000);
404+
const struct rockchip_cpuclk_rate_table *rate;
405+
unsigned long flags;
406+
407+
rate = rockchip_get_cpuclk_settings(cpuclk, new_rate);
408+
if (!rate) {
409+
pr_err("%s: Invalid rate : %lu for cpuclk\n",
410+
__func__, new_rate);
411+
return -EINVAL;
412+
}
413+
414+
if (new_rate > ndata->old_rate) {
415+
spin_lock_irqsave(cpuclk->lock, flags);
416+
rockchip_cpuclk_set_dividers(cpuclk, rate);
417+
spin_unlock_irqrestore(cpuclk->lock, flags);
418+
}
419+
420+
return 0;
421+
}
422+
423+
static int rockchip_cpuclk_multi_pll_post_rate_change(struct rockchip_cpuclk *cpuclk,
424+
struct clk_notifier_data *ndata)
425+
{
426+
unsigned long new_rate = roundup(ndata->new_rate, 1000);
427+
const struct rockchip_cpuclk_rate_table *rate;
428+
unsigned long flags;
429+
430+
rate = rockchip_get_cpuclk_settings(cpuclk, new_rate);
431+
if (!rate) {
432+
pr_err("%s: Invalid rate : %lu for cpuclk\n",
433+
__func__, new_rate);
434+
return -EINVAL;
435+
}
436+
437+
if (new_rate < ndata->old_rate) {
438+
spin_lock_irqsave(cpuclk->lock, flags);
439+
rockchip_cpuclk_set_dividers(cpuclk, rate);
440+
spin_unlock_irqrestore(cpuclk->lock, flags);
441+
}
442+
443+
return 0;
444+
}
445+
446+
static int rockchip_cpuclk_multi_pll_notifier_cb(struct notifier_block *nb,
447+
unsigned long event, void *data)
448+
{
449+
struct clk_notifier_data *ndata = data;
450+
struct rockchip_cpuclk *cpuclk = to_rockchip_cpuclk_nb(nb);
451+
int ret = 0;
452+
453+
pr_debug("%s: event %lu, old_rate %lu, new_rate: %lu\n",
454+
__func__, event, ndata->old_rate, ndata->new_rate);
455+
if (event == PRE_RATE_CHANGE)
456+
ret = rockchip_cpuclk_multi_pll_pre_rate_change(cpuclk, ndata);
457+
else if (event == POST_RATE_CHANGE)
458+
ret = rockchip_cpuclk_multi_pll_post_rate_change(cpuclk, ndata);
459+
460+
return notifier_from_errno(ret);
461+
}
462+
463+
struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name,
464+
const char *const *parent_names,
465+
u8 num_parents, void __iomem *base,
466+
int muxdiv_offset, u8 mux_shift,
467+
u8 mux_width, u8 mux_flags,
468+
int div_offset, u8 div_shift,
469+
u8 div_width, u8 div_flags,
470+
unsigned long flags, spinlock_t *lock,
471+
const struct rockchip_cpuclk_rate_table *rates,
472+
int nrates)
473+
{
474+
struct rockchip_cpuclk *cpuclk;
475+
struct clk_hw *hw;
476+
struct clk_mux *mux = NULL;
477+
struct clk_divider *div = NULL;
478+
const struct clk_ops *mux_ops = NULL, *div_ops = NULL;
479+
int ret;
480+
481+
if (num_parents > 1) {
482+
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
483+
if (!mux)
484+
return ERR_PTR(-ENOMEM);
485+
486+
mux->reg = base + muxdiv_offset;
487+
mux->shift = mux_shift;
488+
mux->mask = BIT(mux_width) - 1;
489+
mux->flags = mux_flags;
490+
mux->lock = lock;
491+
mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops
492+
: &clk_mux_ops;
493+
}
494+
495+
if (div_width > 0) {
496+
div = kzalloc(sizeof(*div), GFP_KERNEL);
497+
if (!div) {
498+
ret = -ENOMEM;
499+
goto free_mux;
500+
}
501+
502+
div->flags = div_flags;
503+
if (div_offset)
504+
div->reg = base + div_offset;
505+
else
506+
div->reg = base + muxdiv_offset;
507+
div->shift = div_shift;
508+
div->width = div_width;
509+
div->lock = lock;
510+
div_ops = (div_flags & CLK_DIVIDER_READ_ONLY)
511+
? &clk_divider_ro_ops
512+
: &clk_divider_ops;
513+
}
514+
515+
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
516+
mux ? &mux->hw : NULL, mux_ops,
517+
div ? &div->hw : NULL, div_ops,
518+
NULL, NULL, flags);
519+
if (IS_ERR(hw)) {
520+
ret = PTR_ERR(hw);
521+
goto free_div;
522+
}
523+
524+
cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL);
525+
if (!cpuclk) {
526+
ret = -ENOMEM;
527+
goto unregister_clk;
528+
}
529+
530+
cpuclk->reg_base = base;
531+
cpuclk->lock = lock;
532+
cpuclk->clk_nb.notifier_call = rockchip_cpuclk_multi_pll_notifier_cb;
533+
ret = clk_notifier_register(hw->clk, &cpuclk->clk_nb);
534+
if (ret) {
535+
pr_err("%s: failed to register clock notifier for %s\n",
536+
__func__, name);
537+
goto free_cpuclk;
538+
}
539+
540+
if (nrates > 0) {
541+
cpuclk->rate_count = nrates;
542+
cpuclk->rate_table = kmemdup(rates,
543+
sizeof(*rates) * nrates,
544+
GFP_KERNEL);
545+
if (!cpuclk->rate_table) {
546+
ret = -ENOMEM;
547+
goto free_cpuclk;
548+
}
549+
}
550+
551+
return hw->clk;
552+
553+
free_cpuclk:
554+
kfree(cpuclk);
555+
unregister_clk:
556+
clk_hw_unregister_composite(hw);
557+
free_div:
558+
kfree(div);
559+
free_mux:
560+
kfree(mux);
561+
562+
return ERR_PTR(ret);
563+
}

0 commit comments

Comments
 (0)