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+
269249static 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