12
12
#include <dt-bindings/clock/rockchip,rk3588-cru.h>
13
13
#include "clk.h"
14
14
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
-
37
15
#define RK3588_GRF_SOC_STATUS0 0x600
38
16
#define RK3588_PHYREF_ALT_GATE 0xc38
39
17
@@ -266,6 +244,8 @@ static struct rockchip_pll_rate_table rk3588_pll_rates[] = {
266
244
}, \
267
245
}
268
246
247
+ static struct rockchip_clk_provider * early_ctx ;
248
+
269
249
static struct rockchip_cpuclk_rate_table rk3588_cpub0clk_rates [] __initdata = {
270
250
RK3588_CPUB01CLK_RATE (2496000000 , 1 ),
271
251
RK3588_CPUB01CLK_RATE (2400000000 , 1 ),
@@ -694,7 +674,7 @@ static struct rockchip_pll_clock rk3588_pll_clks[] __initdata = {
694
674
RK3588_MODE_CON0 , 10 , 15 , 0 , rk3588_pll_rates ),
695
675
};
696
676
697
- static struct rockchip_clk_branch rk3588_clk_branches [] __initdata = {
677
+ static struct rockchip_clk_branch rk3588_early_clk_branches [] __initdata = {
698
678
/*
699
679
* CRU Clock-Architecture
700
680
*/
@@ -792,10 +772,10 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
792
772
COMPOSITE (MCLK_GMAC0_OUT , "mclk_gmac0_out" , gpll_cpll_p , 0 ,
793
773
RK3588_CLKSEL_CON (15 ), 7 , 1 , MFLAGS , 0 , 7 , DFLAGS ,
794
774
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 ,
796
776
RK3588_CLKSEL_CON (15 ), 15 , 1 , MFLAGS , 8 , 7 , DFLAGS ,
797
777
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 ,
799
779
RK3588_CLKSEL_CON (16 ), 7 , 1 , MFLAGS , 0 , 7 , DFLAGS ,
800
780
RK3588_CLKGATE_CON (5 ), 5 , GFLAGS ),
801
781
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 = {
1456
1436
COMPOSITE_NODIV (HCLK_NVM_ROOT , "hclk_nvm_root" , mux_200m_100m_50m_24m_p , 0 ,
1457
1437
RK3588_CLKSEL_CON (77 ), 0 , 2 , MFLAGS ,
1458
1438
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 ,
1460
1440
RK3588_CLKSEL_CON (77 ), 7 , 1 , MFLAGS , 2 , 5 , DFLAGS ,
1461
1441
RK3588_CLKGATE_CON (31 ), 1 , GFLAGS ),
1462
1442
GATE (ACLK_EMMC , "aclk_emmc" , "aclk_nvm_root" , 0 ,
@@ -1685,13 +1665,13 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
1685
1665
RK3588_CLKGATE_CON (42 ), 9 , GFLAGS ),
1686
1666
1687
1667
/* 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 ,
1689
1669
RK3588_CLKSEL_CON (98 ), 5 , 2 , MFLAGS , 0 , 5 , DFLAGS ,
1690
1670
RK3588_CLKGATE_CON (44 ), 0 , GFLAGS ),
1691
1671
COMPOSITE_NODIV (ACLK_VDPU_LOW_ROOT , "aclk_vdpu_low_root" , mux_400m_200m_100m_24m_p , 0 ,
1692
1672
RK3588_CLKSEL_CON (98 ), 7 , 2 , MFLAGS ,
1693
1673
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 ,
1695
1675
RK3588_CLKSEL_CON (98 ), 9 , 2 , MFLAGS ,
1696
1676
RK3588_CLKGATE_CON (44 ), 2 , GFLAGS ),
1697
1677
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 = {
1742
1722
COMPOSITE (ACLK_RKVENC0_ROOT , "aclk_rkvenc0_root" , gpll_cpll_npll_p , 0 ,
1743
1723
RK3588_CLKSEL_CON (102 ), 7 , 2 , MFLAGS , 2 , 5 , DFLAGS ,
1744
1724
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 ,
1746
1726
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 ,
1748
1728
RK3588_CLKGATE_CON (47 ), 5 , GFLAGS ),
1749
1729
COMPOSITE (CLK_RKVENC0_CORE , "clk_rkvenc0_core" , gpll_cpll_aupll_npll_p , 0 ,
1750
1730
RK3588_CLKSEL_CON (102 ), 14 , 2 , MFLAGS , 9 , 5 , DFLAGS ,
@@ -1754,10 +1734,10 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
1754
1734
RK3588_CLKGATE_CON (48 ), 6 , GFLAGS ),
1755
1735
1756
1736
/* 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 ,
1758
1738
RK3588_CLKSEL_CON (106 ), 5 , 3 , MFLAGS , 0 , 5 , DFLAGS ,
1759
1739
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 ,
1761
1741
RK3588_CLKSEL_CON (106 ), 8 , 2 , MFLAGS ,
1762
1742
RK3588_CLKGATE_CON (49 ), 1 , GFLAGS ),
1763
1743
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 = {
1927
1907
COMPOSITE (ACLK_VOP_ROOT , "aclk_vop_root" , gpll_cpll_dmyaupll_npll_spll_p , 0 ,
1928
1908
RK3588_CLKSEL_CON (110 ), 5 , 3 , MFLAGS , 0 , 5 , DFLAGS ,
1929
1909
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 ,
1931
1911
RK3588_CLKSEL_CON (110 ), 8 , 2 , MFLAGS ,
1932
1912
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 ,
1934
1914
RK3588_CLKSEL_CON (110 ), 10 , 2 , MFLAGS ,
1935
1915
RK3588_CLKGATE_CON (52 ), 2 , GFLAGS ),
1936
1916
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 = {
2428
2408
RK3588_CLKGATE_CON (68 ), 5 , GFLAGS ),
2429
2409
GATE (ACLK_AV1 , "aclk_av1" , "aclk_av1_pre" , 0 ,
2430
2410
RK3588_CLKGATE_CON (68 ), 2 , GFLAGS ),
2411
+ };
2431
2412
2413
+ static struct rockchip_clk_branch rk3588_clk_branches [] = {
2432
2414
GATE_LINK (ACLK_ISP1_PRE , "aclk_isp1_pre" , "aclk_isp1_root" , ACLK_VI_ROOT , 0 , RK3588_CLKGATE_CON (26 ), 6 , GFLAGS ),
2433
2415
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 ),
2435
2417
GATE_LINK (ACLK_USB , "aclk_usb" , "aclk_usb_root" , ACLK_VO1USB_TOP_ROOT , 0 , RK3588_CLKGATE_CON (42 ), 2 , GFLAGS ),
2436
2418
GATE_LINK (HCLK_USB , "hclk_usb" , "hclk_usb_root" , HCLK_VO1USB_TOP_ROOT , 0 , RK3588_CLKGATE_CON (42 ), 3 , GFLAGS ),
2437
2419
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 = {
2443
2425
GATE_LINK (HCLK_RKVDEC1_PRE , "hclk_rkvdec1_pre" , "hclk_rkvdec1_root" , HCLK_VDPU_ROOT , 0 , RK3588_CLKGATE_CON (41 ), 4 , GFLAGS ),
2444
2426
GATE_LINK (ACLK_RKVDEC1_PRE , "aclk_rkvdec1_pre" , "aclk_rkvdec1_root" , ACLK_VDPU_ROOT , 0 , RK3588_CLKGATE_CON (41 ), 5 , GFLAGS ),
2445
2427
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 ),
2447
2429
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 ),
2449
2431
GATE_LINK (ACLK_AV1_PRE , "aclk_av1_pre" , "aclk_av1_root" , ACLK_VDPU_ROOT , 0 , RK3588_CLKGATE_CON (68 ), 1 , GFLAGS ),
2450
2432
GATE_LINK (PCLK_AV1_PRE , "pclk_av1_pre" , "pclk_av1_root" , HCLK_VDPU_ROOT , 0 , RK3588_CLKGATE_CON (68 ), 4 , GFLAGS ),
2451
2433
GATE_LINK (HCLK_SDIO_PRE , "hclk_sdio_pre" , "hclk_sdio_root" , HCLK_NVM , 0 , RK3588_CLKGATE_CON (75 ), 1 , GFLAGS ),
2452
2434
GATE_LINK (PCLK_VO0GRF , "pclk_vo0grf" , "pclk_vo0_root" , HCLK_VO0 , CLK_IGNORE_UNUSED , RK3588_CLKGATE_CON (55 ), 10 , GFLAGS ),
2453
2435
GATE_LINK (PCLK_VO1GRF , "pclk_vo1grf" , "pclk_vo1_root" , HCLK_VO1 , CLK_IGNORE_UNUSED , RK3588_CLKGATE_CON (59 ), 12 , GFLAGS ),
2454
2436
};
2455
2437
2456
- static void __init rk3588_clk_init (struct device_node * np )
2438
+ static void __init rk3588_clk_early_init (struct device_node * np )
2457
2439
{
2458
2440
struct rockchip_clk_provider * ctx ;
2459
- unsigned long clk_nr_clks ;
2441
+ unsigned long clk_nr_clks , max_clk_id1 , max_clk_id2 ;
2460
2442
void __iomem * reg_base ;
2461
2443
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
+
2464
2450
reg_base = of_iomap (np , 0 );
2465
2451
if (!reg_base ) {
2466
2452
pr_err ("%s: could not map cru region\n" , __func__ );
2467
2453
return ;
2468
2454
}
2469
2455
2470
- ctx = rockchip_clk_init (np , reg_base , clk_nr_clks );
2456
+ ctx = rockchip_clk_init_early (np , reg_base , clk_nr_clks );
2471
2457
if (IS_ERR (ctx )) {
2472
2458
pr_err ("%s: rockchip clk init failed\n" , __func__ );
2473
2459
iounmap (reg_base );
2474
2460
return ;
2475
2461
}
2462
+ early_ctx = ctx ;
2476
2463
2477
2464
rockchip_clk_register_plls (ctx , rk3588_pll_clks ,
2478
2465
ARRAY_SIZE (rk3588_pll_clks ),
@@ -2491,14 +2478,55 @@ static void __init rk3588_clk_init(struct device_node *np)
2491
2478
& rk3588_cpub1clk_data , rk3588_cpub1clk_rates ,
2492
2479
ARRAY_SIZE (rk3588_cpub1clk_rates ));
2493
2480
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 ));
2496
2496
2497
- rk3588_rst_init ( np , reg_base );
2497
+ rockchip_clk_finalize ( ctx );
2498
2498
2499
+ rk3588_rst_init (np , ctx -> reg_base );
2499
2500
rockchip_register_restart_notifier (ctx , RK3588_GLB_SRST_FST , NULL );
2500
2501
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 );
2501
2507
rockchip_clk_of_add_provider (np , ctx );
2508
+
2509
+ return 0 ;
2502
2510
}
2503
2511
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