Skip to content

Commit 57ea142

Browse files
committed
Merge tag 'v6.14-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: Real handling of the linked clocks (clocks of the interconnect port a peripheral is connected to) on rk3588 using pm-clocks, allowing us to stop marking them as critical and one more rk3588 critical clock, that the kernel cannot handle otherwise right now. * tag 'v6.14-rockchip-clk1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip: clk: rockchip: rk3588: make refclko25m_ethX critical clk: rockchip: rk3588: drop RK3588_LINKED_CLK clk: rockchip: implement linked gate clock support clk: rockchip: expose rockchip_clk_set_lookup clk: rockchip: rk3588: register GATE_LINK later clk: rockchip: support clocks registered late
2 parents 40384c8 + cd8b536 commit 57ea142

File tree

5 files changed

+288
-60
lines changed

5 files changed

+288
-60
lines changed

drivers/clk/rockchip/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ clk-rockchip-y += clk-inverter.o
1313
clk-rockchip-y += clk-mmc-phase.o
1414
clk-rockchip-y += clk-muxgrf.o
1515
clk-rockchip-y += clk-ddr.o
16+
clk-rockchip-y += gate-link.o
1617
clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
1718

1819
obj-$(CONFIG_CLK_PX30) += clk-px30.o

drivers/clk/rockchip/clk-rk3588.c

Lines changed: 74 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,6 @@
1212
#include <dt-bindings/clock/rockchip,rk3588-cru.h>
1313
#include "clk.h"
1414

15-
/*
16-
* Recent Rockchip SoCs have a new hardware block called Native Interface
17-
* Unit (NIU), which gates clocks to devices behind them. These effectively
18-
* need two parent clocks.
19-
*
20-
* Downstream enables the linked clock via runtime PM whenever the gate is
21-
* enabled. This implementation uses separate clock nodes for each of the
22-
* linked gate clocks, which leaks parts of the clock tree into DT.
23-
*
24-
* The GATE_LINK macro instead takes the second parent via 'linkname', but
25-
* ignores the information. Once the clock framework is ready to handle it, the
26-
* information should be passed on here. But since these clocks are required to
27-
* access multiple relevant IP blocks, such as PCIe or USB, we mark all linked
28-
* clocks critical until a better solution is available. This will waste some
29-
* power, but avoids leaking implementation details into DT or hanging the
30-
* system.
31-
*/
32-
#define GATE_LINK(_id, cname, pname, linkedclk, f, o, b, gf) \
33-
GATE(_id, cname, pname, f, o, b, gf)
34-
#define RK3588_LINKED_CLK CLK_IS_CRITICAL
35-
36-
3715
#define RK3588_GRF_SOC_STATUS0 0x600
3816
#define RK3588_PHYREF_ALT_GATE 0xc38
3917

@@ -266,6 +244,8 @@ static struct rockchip_pll_rate_table rk3588_pll_rates[] = {
266244
}, \
267245
}
268246

247+
static struct rockchip_clk_provider *early_ctx;
248+
269249
static struct rockchip_cpuclk_rate_table rk3588_cpub0clk_rates[] __initdata = {
270250
RK3588_CPUB01CLK_RATE(2496000000, 1),
271251
RK3588_CPUB01CLK_RATE(2400000000, 1),
@@ -694,7 +674,7 @@ static struct rockchip_pll_clock rk3588_pll_clks[] __initdata = {
694674
RK3588_MODE_CON0, 10, 15, 0, rk3588_pll_rates),
695675
};
696676

697-
static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
677+
static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = {
698678
/*
699679
* CRU Clock-Architecture
700680
*/
@@ -792,10 +772,10 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
792772
COMPOSITE(MCLK_GMAC0_OUT, "mclk_gmac0_out", gpll_cpll_p, 0,
793773
RK3588_CLKSEL_CON(15), 7, 1, MFLAGS, 0, 7, DFLAGS,
794774
RK3588_CLKGATE_CON(5), 3, GFLAGS),
795-
COMPOSITE(REFCLKO25M_ETH0_OUT, "refclko25m_eth0_out", gpll_cpll_p, 0,
775+
COMPOSITE(REFCLKO25M_ETH0_OUT, "refclko25m_eth0_out", gpll_cpll_p, CLK_IS_CRITICAL,
796776
RK3588_CLKSEL_CON(15), 15, 1, MFLAGS, 8, 7, DFLAGS,
797777
RK3588_CLKGATE_CON(5), 4, GFLAGS),
798-
COMPOSITE(REFCLKO25M_ETH1_OUT, "refclko25m_eth1_out", gpll_cpll_p, 0,
778+
COMPOSITE(REFCLKO25M_ETH1_OUT, "refclko25m_eth1_out", gpll_cpll_p, CLK_IS_CRITICAL,
799779
RK3588_CLKSEL_CON(16), 7, 1, MFLAGS, 0, 7, DFLAGS,
800780
RK3588_CLKGATE_CON(5), 5, GFLAGS),
801781
COMPOSITE(CLK_CIFOUT_OUT, "clk_cifout_out", gpll_cpll_24m_spll_p, 0,
@@ -1456,7 +1436,7 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
14561436
COMPOSITE_NODIV(HCLK_NVM_ROOT, "hclk_nvm_root", mux_200m_100m_50m_24m_p, 0,
14571437
RK3588_CLKSEL_CON(77), 0, 2, MFLAGS,
14581438
RK3588_CLKGATE_CON(31), 0, GFLAGS),
1459-
COMPOSITE(ACLK_NVM_ROOT, "aclk_nvm_root", gpll_cpll_p, RK3588_LINKED_CLK,
1439+
COMPOSITE(ACLK_NVM_ROOT, "aclk_nvm_root", gpll_cpll_p, 0,
14601440
RK3588_CLKSEL_CON(77), 7, 1, MFLAGS, 2, 5, DFLAGS,
14611441
RK3588_CLKGATE_CON(31), 1, GFLAGS),
14621442
GATE(ACLK_EMMC, "aclk_emmc", "aclk_nvm_root", 0,
@@ -1685,13 +1665,13 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
16851665
RK3588_CLKGATE_CON(42), 9, GFLAGS),
16861666

16871667
/* vdpu */
1688-
COMPOSITE(ACLK_VDPU_ROOT, "aclk_vdpu_root", gpll_cpll_aupll_p, RK3588_LINKED_CLK,
1668+
COMPOSITE(ACLK_VDPU_ROOT, "aclk_vdpu_root", gpll_cpll_aupll_p, 0,
16891669
RK3588_CLKSEL_CON(98), 5, 2, MFLAGS, 0, 5, DFLAGS,
16901670
RK3588_CLKGATE_CON(44), 0, GFLAGS),
16911671
COMPOSITE_NODIV(ACLK_VDPU_LOW_ROOT, "aclk_vdpu_low_root", mux_400m_200m_100m_24m_p, 0,
16921672
RK3588_CLKSEL_CON(98), 7, 2, MFLAGS,
16931673
RK3588_CLKGATE_CON(44), 1, GFLAGS),
1694-
COMPOSITE_NODIV(HCLK_VDPU_ROOT, "hclk_vdpu_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK,
1674+
COMPOSITE_NODIV(HCLK_VDPU_ROOT, "hclk_vdpu_root", mux_200m_100m_50m_24m_p, 0,
16951675
RK3588_CLKSEL_CON(98), 9, 2, MFLAGS,
16961676
RK3588_CLKGATE_CON(44), 2, GFLAGS),
16971677
COMPOSITE(ACLK_JPEG_DECODER_ROOT, "aclk_jpeg_decoder_root", gpll_cpll_aupll_spll_p, 0,
@@ -1742,9 +1722,9 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
17421722
COMPOSITE(ACLK_RKVENC0_ROOT, "aclk_rkvenc0_root", gpll_cpll_npll_p, 0,
17431723
RK3588_CLKSEL_CON(102), 7, 2, MFLAGS, 2, 5, DFLAGS,
17441724
RK3588_CLKGATE_CON(47), 1, GFLAGS),
1745-
GATE(HCLK_RKVENC0, "hclk_rkvenc0", "hclk_rkvenc0_root", RK3588_LINKED_CLK,
1725+
GATE(HCLK_RKVENC0, "hclk_rkvenc0", "hclk_rkvenc0_root", 0,
17461726
RK3588_CLKGATE_CON(47), 4, GFLAGS),
1747-
GATE(ACLK_RKVENC0, "aclk_rkvenc0", "aclk_rkvenc0_root", RK3588_LINKED_CLK,
1727+
GATE(ACLK_RKVENC0, "aclk_rkvenc0", "aclk_rkvenc0_root", 0,
17481728
RK3588_CLKGATE_CON(47), 5, GFLAGS),
17491729
COMPOSITE(CLK_RKVENC0_CORE, "clk_rkvenc0_core", gpll_cpll_aupll_npll_p, 0,
17501730
RK3588_CLKSEL_CON(102), 14, 2, MFLAGS, 9, 5, DFLAGS,
@@ -1754,10 +1734,10 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
17541734
RK3588_CLKGATE_CON(48), 6, GFLAGS),
17551735

17561736
/* vi */
1757-
COMPOSITE(ACLK_VI_ROOT, "aclk_vi_root", gpll_cpll_npll_aupll_spll_p, RK3588_LINKED_CLK,
1737+
COMPOSITE(ACLK_VI_ROOT, "aclk_vi_root", gpll_cpll_npll_aupll_spll_p, 0,
17581738
RK3588_CLKSEL_CON(106), 5, 3, MFLAGS, 0, 5, DFLAGS,
17591739
RK3588_CLKGATE_CON(49), 0, GFLAGS),
1760-
COMPOSITE_NODIV(HCLK_VI_ROOT, "hclk_vi_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK,
1740+
COMPOSITE_NODIV(HCLK_VI_ROOT, "hclk_vi_root", mux_200m_100m_50m_24m_p, 0,
17611741
RK3588_CLKSEL_CON(106), 8, 2, MFLAGS,
17621742
RK3588_CLKGATE_CON(49), 1, GFLAGS),
17631743
COMPOSITE_NODIV(PCLK_VI_ROOT, "pclk_vi_root", mux_100m_50m_24m_p, 0,
@@ -1927,10 +1907,10 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
19271907
COMPOSITE(ACLK_VOP_ROOT, "aclk_vop_root", gpll_cpll_dmyaupll_npll_spll_p, 0,
19281908
RK3588_CLKSEL_CON(110), 5, 3, MFLAGS, 0, 5, DFLAGS,
19291909
RK3588_CLKGATE_CON(52), 0, GFLAGS),
1930-
COMPOSITE_NODIV(ACLK_VOP_LOW_ROOT, "aclk_vop_low_root", mux_400m_200m_100m_24m_p, RK3588_LINKED_CLK,
1910+
COMPOSITE_NODIV(ACLK_VOP_LOW_ROOT, "aclk_vop_low_root", mux_400m_200m_100m_24m_p, 0,
19311911
RK3588_CLKSEL_CON(110), 8, 2, MFLAGS,
19321912
RK3588_CLKGATE_CON(52), 1, GFLAGS),
1933-
COMPOSITE_NODIV(HCLK_VOP_ROOT, "hclk_vop_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK,
1913+
COMPOSITE_NODIV(HCLK_VOP_ROOT, "hclk_vop_root", mux_200m_100m_50m_24m_p, 0,
19341914
RK3588_CLKSEL_CON(110), 10, 2, MFLAGS,
19351915
RK3588_CLKGATE_CON(52), 2, GFLAGS),
19361916
COMPOSITE_NODIV(PCLK_VOP_ROOT, "pclk_vop_root", mux_100m_50m_24m_p, 0,
@@ -2428,10 +2408,12 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
24282408
RK3588_CLKGATE_CON(68), 5, GFLAGS),
24292409
GATE(ACLK_AV1, "aclk_av1", "aclk_av1_pre", 0,
24302410
RK3588_CLKGATE_CON(68), 2, GFLAGS),
2411+
};
24312412

2413+
static struct rockchip_clk_branch rk3588_clk_branches[] = {
24322414
GATE_LINK(ACLK_ISP1_PRE, "aclk_isp1_pre", "aclk_isp1_root", ACLK_VI_ROOT, 0, RK3588_CLKGATE_CON(26), 6, GFLAGS),
24332415
GATE_LINK(HCLK_ISP1_PRE, "hclk_isp1_pre", "hclk_isp1_root", HCLK_VI_ROOT, 0, RK3588_CLKGATE_CON(26), 8, GFLAGS),
2434-
GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", ACLK_NVM_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(31), 2, GFLAGS),
2416+
GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", ACLK_NVM_ROOT, 0, RK3588_CLKGATE_CON(31), 2, GFLAGS),
24352417
GATE_LINK(ACLK_USB, "aclk_usb", "aclk_usb_root", ACLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(42), 2, GFLAGS),
24362418
GATE_LINK(HCLK_USB, "hclk_usb", "hclk_usb_root", HCLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(42), 3, GFLAGS),
24372419
GATE_LINK(ACLK_JPEG_DECODER_PRE, "aclk_jpeg_decoder_pre", "aclk_jpeg_decoder_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(44), 7, GFLAGS),
@@ -2443,36 +2425,41 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
24432425
GATE_LINK(HCLK_RKVDEC1_PRE, "hclk_rkvdec1_pre", "hclk_rkvdec1_root", HCLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(41), 4, GFLAGS),
24442426
GATE_LINK(ACLK_RKVDEC1_PRE, "aclk_rkvdec1_pre", "aclk_rkvdec1_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(41), 5, GFLAGS),
24452427
GATE_LINK(ACLK_HDCP0_PRE, "aclk_hdcp0_pre", "aclk_vo0_root", ACLK_VOP_LOW_ROOT, 0, RK3588_CLKGATE_CON(55), 9, GFLAGS),
2446-
GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", HCLK_VOP_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(55), 5, GFLAGS),
2428+
GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", HCLK_VOP_ROOT, 0, RK3588_CLKGATE_CON(55), 5, GFLAGS),
24472429
GATE_LINK(ACLK_HDCP1_PRE, "aclk_hdcp1_pre", "aclk_hdcp1_root", ACLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(59), 6, GFLAGS),
2448-
GATE_LINK(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", HCLK_VO1USB_TOP_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(59), 9, GFLAGS),
2430+
GATE_LINK(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", HCLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(59), 9, GFLAGS),
24492431
GATE_LINK(ACLK_AV1_PRE, "aclk_av1_pre", "aclk_av1_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(68), 1, GFLAGS),
24502432
GATE_LINK(PCLK_AV1_PRE, "pclk_av1_pre", "pclk_av1_root", HCLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(68), 4, GFLAGS),
24512433
GATE_LINK(HCLK_SDIO_PRE, "hclk_sdio_pre", "hclk_sdio_root", HCLK_NVM, 0, RK3588_CLKGATE_CON(75), 1, GFLAGS),
24522434
GATE_LINK(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", HCLK_VO0, CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(55), 10, GFLAGS),
24532435
GATE_LINK(PCLK_VO1GRF, "pclk_vo1grf", "pclk_vo1_root", HCLK_VO1, CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(59), 12, GFLAGS),
24542436
};
24552437

2456-
static void __init rk3588_clk_init(struct device_node *np)
2438+
static void __init rk3588_clk_early_init(struct device_node *np)
24572439
{
24582440
struct rockchip_clk_provider *ctx;
2459-
unsigned long clk_nr_clks;
2441+
unsigned long clk_nr_clks, max_clk_id1, max_clk_id2;
24602442
void __iomem *reg_base;
24612443

2462-
clk_nr_clks = rockchip_clk_find_max_clk_id(rk3588_clk_branches,
2463-
ARRAY_SIZE(rk3588_clk_branches)) + 1;
2444+
max_clk_id1 = rockchip_clk_find_max_clk_id(rk3588_clk_branches,
2445+
ARRAY_SIZE(rk3588_clk_branches));
2446+
max_clk_id2 = rockchip_clk_find_max_clk_id(rk3588_early_clk_branches,
2447+
ARRAY_SIZE(rk3588_early_clk_branches));
2448+
clk_nr_clks = max(max_clk_id1, max_clk_id2) + 1;
2449+
24642450
reg_base = of_iomap(np, 0);
24652451
if (!reg_base) {
24662452
pr_err("%s: could not map cru region\n", __func__);
24672453
return;
24682454
}
24692455

2470-
ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
2456+
ctx = rockchip_clk_init_early(np, reg_base, clk_nr_clks);
24712457
if (IS_ERR(ctx)) {
24722458
pr_err("%s: rockchip clk init failed\n", __func__);
24732459
iounmap(reg_base);
24742460
return;
24752461
}
2462+
early_ctx = ctx;
24762463

24772464
rockchip_clk_register_plls(ctx, rk3588_pll_clks,
24782465
ARRAY_SIZE(rk3588_pll_clks),
@@ -2491,14 +2478,55 @@ static void __init rk3588_clk_init(struct device_node *np)
24912478
&rk3588_cpub1clk_data, rk3588_cpub1clk_rates,
24922479
ARRAY_SIZE(rk3588_cpub1clk_rates));
24932480

2494-
rockchip_clk_register_branches(ctx, rk3588_clk_branches,
2495-
ARRAY_SIZE(rk3588_clk_branches));
2481+
rockchip_clk_register_branches(ctx, rk3588_early_clk_branches,
2482+
ARRAY_SIZE(rk3588_early_clk_branches));
2483+
2484+
rockchip_clk_of_add_provider(np, ctx);
2485+
}
2486+
CLK_OF_DECLARE_DRIVER(rk3588_cru, "rockchip,rk3588-cru", rk3588_clk_early_init);
2487+
2488+
static int clk_rk3588_probe(struct platform_device *pdev)
2489+
{
2490+
struct rockchip_clk_provider *ctx = early_ctx;
2491+
struct device *dev = &pdev->dev;
2492+
struct device_node *np = dev->of_node;
2493+
2494+
rockchip_clk_register_late_branches(dev, ctx, rk3588_clk_branches,
2495+
ARRAY_SIZE(rk3588_clk_branches));
24962496

2497-
rk3588_rst_init(np, reg_base);
2497+
rockchip_clk_finalize(ctx);
24982498

2499+
rk3588_rst_init(np, ctx->reg_base);
24992500
rockchip_register_restart_notifier(ctx, RK3588_GLB_SRST_FST, NULL);
25002501

2502+
/*
2503+
* Re-add clock provider, so that the newly added clocks are also
2504+
* re-parented and get their defaults configured.
2505+
*/
2506+
of_clk_del_provider(np);
25012507
rockchip_clk_of_add_provider(np, ctx);
2508+
2509+
return 0;
25022510
}
25032511

2504-
CLK_OF_DECLARE(rk3588_cru, "rockchip,rk3588-cru", rk3588_clk_init);
2512+
static const struct of_device_id clk_rk3588_match_table[] = {
2513+
{
2514+
.compatible = "rockchip,rk3588-cru",
2515+
},
2516+
{ }
2517+
};
2518+
2519+
static struct platform_driver clk_rk3588_driver = {
2520+
.probe = clk_rk3588_probe,
2521+
.driver = {
2522+
.name = "clk-rk3588",
2523+
.of_match_table = clk_rk3588_match_table,
2524+
.suppress_bind_attrs = true,
2525+
},
2526+
};
2527+
2528+
static int __init rockchip_clk_rk3588_drv_register(void)
2529+
{
2530+
return platform_driver_register(&clk_rk3588_driver);
2531+
}
2532+
core_initcall(rockchip_clk_rk3588_drv_register);

0 commit comments

Comments
 (0)