166af5425SGhennadi Procopciuc /* 247b3a825SGhennadi Procopciuc * Copyright 2024-2025 NXP 366af5425SGhennadi Procopciuc * 466af5425SGhennadi Procopciuc * SPDX-License-Identifier: BSD-3-Clause 566af5425SGhennadi Procopciuc */ 666af5425SGhennadi Procopciuc #include <drivers/clk.h> 7e4462daeSGhennadi Procopciuc #include <platform_def.h> 866af5425SGhennadi Procopciuc #include <s32cc-clk-drv.h> 966af5425SGhennadi Procopciuc #include <s32cc-clk-ids.h> 1066af5425SGhennadi Procopciuc #include <s32cc-clk-utils.h> 1166af5425SGhennadi Procopciuc 1266af5425SGhennadi Procopciuc #define S32CC_FXOSC_FREQ (40U * MHZ) 137ad4e231SGhennadi Procopciuc #define S32CC_ARM_PLL_VCO_FREQ (2U * GHZ) 14de950ef0SGhennadi Procopciuc #define S32CC_ARM_PLL_PHI0_FREQ (1U * GHZ) 1564e0c226SGhennadi Procopciuc #define S32CC_A53_FREQ (1U * GHZ) 16b8ad8800SGhennadi Procopciuc #define S32CC_XBAR_2X_FREQ (800U * MHZ) 178653352aSGhennadi Procopciuc #define S32CC_PERIPH_PLL_VCO_FREQ (2U * GHZ) 18e4462daeSGhennadi Procopciuc #define S32CC_PERIPH_PLL_PHI3_FREQ UART_CLOCK_HZ 1918c2b137SGhennadi Procopciuc #define S32CC_DDR_PLL_VCO_FREQ (1600U * MHZ) 2018c2b137SGhennadi Procopciuc #define S32CC_DDR_PLL_PHI0_FREQ (800U * MHZ) 2147b3a825SGhennadi Procopciuc #define S32CC_PERIPH_DFS_PHI3_FREQ (800U * MHZ) 22*9c640e09SGhennadi Procopciuc #define S32CC_USDHC_FREQ (200U * MHZ) 2366af5425SGhennadi Procopciuc 245300040bSGhennadi Procopciuc static int setup_fxosc(void) 2566af5425SGhennadi Procopciuc { 2666af5425SGhennadi Procopciuc int ret; 2766af5425SGhennadi Procopciuc 28d3869455SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL); 29d3869455SGhennadi Procopciuc if (ret != 0) { 30d3869455SGhennadi Procopciuc return ret; 31d3869455SGhennadi Procopciuc } 32d3869455SGhennadi Procopciuc 33d3869455SGhennadi Procopciuc return ret; 34d3869455SGhennadi Procopciuc } 35d3869455SGhennadi Procopciuc 365300040bSGhennadi Procopciuc static int setup_arm_pll(void) 37d3869455SGhennadi Procopciuc { 38d3869455SGhennadi Procopciuc int ret; 3966af5425SGhennadi Procopciuc 4083af4504SGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_ARM_PLL_MUX, S32CC_CLK_FXOSC); 4183af4504SGhennadi Procopciuc if (ret != 0) { 4283af4504SGhennadi Procopciuc return ret; 4383af4504SGhennadi Procopciuc } 4483af4504SGhennadi Procopciuc 457ad4e231SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_ARM_PLL_VCO, S32CC_ARM_PLL_VCO_FREQ, NULL); 467ad4e231SGhennadi Procopciuc if (ret != 0) { 477ad4e231SGhennadi Procopciuc return ret; 487ad4e231SGhennadi Procopciuc } 497ad4e231SGhennadi Procopciuc 50de950ef0SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_ARM_PLL_PHI0, S32CC_ARM_PLL_PHI0_FREQ, NULL); 51de950ef0SGhennadi Procopciuc if (ret != 0) { 52de950ef0SGhennadi Procopciuc return ret; 53de950ef0SGhennadi Procopciuc } 54de950ef0SGhennadi Procopciuc 55b5101c45SGhennadi Procopciuc return ret; 56b5101c45SGhennadi Procopciuc } 57b5101c45SGhennadi Procopciuc 585300040bSGhennadi Procopciuc static int setup_periph_pll(void) 598653352aSGhennadi Procopciuc { 608653352aSGhennadi Procopciuc int ret; 618653352aSGhennadi Procopciuc 628653352aSGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_PERIPH_PLL_MUX, S32CC_CLK_FXOSC); 638653352aSGhennadi Procopciuc if (ret != 0) { 648653352aSGhennadi Procopciuc return ret; 658653352aSGhennadi Procopciuc } 668653352aSGhennadi Procopciuc 678653352aSGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_VCO, S32CC_PERIPH_PLL_VCO_FREQ, NULL); 688653352aSGhennadi Procopciuc if (ret != 0) { 698653352aSGhennadi Procopciuc return ret; 708653352aSGhennadi Procopciuc } 718653352aSGhennadi Procopciuc 728653352aSGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_PHI3, S32CC_PERIPH_PLL_PHI3_FREQ, NULL); 738653352aSGhennadi Procopciuc if (ret != 0) { 748653352aSGhennadi Procopciuc return ret; 758653352aSGhennadi Procopciuc } 768653352aSGhennadi Procopciuc 778653352aSGhennadi Procopciuc return ret; 788653352aSGhennadi Procopciuc } 798653352aSGhennadi Procopciuc 80d3869455SGhennadi Procopciuc static int enable_a53_clk(void) 81d3869455SGhennadi Procopciuc { 82d3869455SGhennadi Procopciuc int ret; 83d3869455SGhennadi Procopciuc 84d3869455SGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_MC_CGM1_MUX0, S32CC_CLK_ARM_PLL_PHI0); 85d3869455SGhennadi Procopciuc if (ret != 0) { 86d3869455SGhennadi Procopciuc return ret; 87d3869455SGhennadi Procopciuc } 88d3869455SGhennadi Procopciuc 89d3869455SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_A53_CORE, S32CC_A53_FREQ, NULL); 90d3869455SGhennadi Procopciuc if (ret != 0) { 91d3869455SGhennadi Procopciuc return ret; 92d3869455SGhennadi Procopciuc } 93d3869455SGhennadi Procopciuc 947004f678SGhennadi Procopciuc ret = clk_enable(S32CC_CLK_A53_CORE); 957004f678SGhennadi Procopciuc if (ret != 0) { 967004f678SGhennadi Procopciuc return ret; 977004f678SGhennadi Procopciuc } 987004f678SGhennadi Procopciuc 9966af5425SGhennadi Procopciuc return ret; 10066af5425SGhennadi Procopciuc } 101d3869455SGhennadi Procopciuc 102b8ad8800SGhennadi Procopciuc static int enable_xbar_clk(void) 103b8ad8800SGhennadi Procopciuc { 104b8ad8800SGhennadi Procopciuc int ret; 105b8ad8800SGhennadi Procopciuc 106b8ad8800SGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX0, S32CC_CLK_ARM_PLL_DFS1); 107b8ad8800SGhennadi Procopciuc if (ret != 0) { 108b8ad8800SGhennadi Procopciuc return ret; 109b8ad8800SGhennadi Procopciuc } 110b8ad8800SGhennadi Procopciuc 111b8ad8800SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_XBAR_2X, S32CC_XBAR_2X_FREQ, NULL); 112b8ad8800SGhennadi Procopciuc if (ret != 0) { 113b8ad8800SGhennadi Procopciuc return ret; 114b8ad8800SGhennadi Procopciuc } 115b8ad8800SGhennadi Procopciuc 116b8ad8800SGhennadi Procopciuc ret = clk_enable(S32CC_CLK_ARM_PLL_DFS1); 117b8ad8800SGhennadi Procopciuc if (ret != 0) { 118b8ad8800SGhennadi Procopciuc return ret; 119b8ad8800SGhennadi Procopciuc } 120b8ad8800SGhennadi Procopciuc 121b8ad8800SGhennadi Procopciuc ret = clk_enable(S32CC_CLK_XBAR_2X); 122b8ad8800SGhennadi Procopciuc if (ret != 0) { 123b8ad8800SGhennadi Procopciuc return ret; 124b8ad8800SGhennadi Procopciuc } 125b8ad8800SGhennadi Procopciuc 126b8ad8800SGhennadi Procopciuc return ret; 127b8ad8800SGhennadi Procopciuc } 128b8ad8800SGhennadi Procopciuc 129e4462daeSGhennadi Procopciuc static int enable_uart_clk(void) 130e4462daeSGhennadi Procopciuc { 131e4462daeSGhennadi Procopciuc int ret; 132e4462daeSGhennadi Procopciuc 133e4462daeSGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX8, S32CC_CLK_PERIPH_PLL_PHI3); 134e4462daeSGhennadi Procopciuc if (ret != 0) { 135e4462daeSGhennadi Procopciuc return ret; 136e4462daeSGhennadi Procopciuc } 137e4462daeSGhennadi Procopciuc 138e4462daeSGhennadi Procopciuc ret = clk_enable(S32CC_CLK_LINFLEX_BAUD); 139e4462daeSGhennadi Procopciuc if (ret != 0) { 140e4462daeSGhennadi Procopciuc return ret; 141e4462daeSGhennadi Procopciuc } 142e4462daeSGhennadi Procopciuc 143e4462daeSGhennadi Procopciuc return ret; 144e4462daeSGhennadi Procopciuc } 145e4462daeSGhennadi Procopciuc 14618c2b137SGhennadi Procopciuc static int setup_ddr_pll(void) 14718c2b137SGhennadi Procopciuc { 14818c2b137SGhennadi Procopciuc int ret; 14918c2b137SGhennadi Procopciuc 15018c2b137SGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_DDR_PLL_MUX, S32CC_CLK_FXOSC); 15118c2b137SGhennadi Procopciuc if (ret != 0) { 15218c2b137SGhennadi Procopciuc return ret; 15318c2b137SGhennadi Procopciuc } 15418c2b137SGhennadi Procopciuc 15518c2b137SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_DDR_PLL_VCO, S32CC_DDR_PLL_VCO_FREQ, NULL); 15618c2b137SGhennadi Procopciuc if (ret != 0) { 15718c2b137SGhennadi Procopciuc return ret; 15818c2b137SGhennadi Procopciuc } 15918c2b137SGhennadi Procopciuc 16018c2b137SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_DDR_PLL_PHI0, S32CC_DDR_PLL_PHI0_FREQ, NULL); 16118c2b137SGhennadi Procopciuc if (ret != 0) { 16218c2b137SGhennadi Procopciuc return ret; 16318c2b137SGhennadi Procopciuc } 16418c2b137SGhennadi Procopciuc 16518c2b137SGhennadi Procopciuc return ret; 16618c2b137SGhennadi Procopciuc } 16718c2b137SGhennadi Procopciuc 1688a4f840bSGhennadi Procopciuc static int enable_ddr_clk(void) 1698a4f840bSGhennadi Procopciuc { 1708a4f840bSGhennadi Procopciuc int ret; 1718a4f840bSGhennadi Procopciuc 1728a4f840bSGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_MC_CGM5_MUX0, S32CC_CLK_DDR_PLL_PHI0); 1738a4f840bSGhennadi Procopciuc if (ret != 0) { 1748a4f840bSGhennadi Procopciuc return ret; 1758a4f840bSGhennadi Procopciuc } 1768a4f840bSGhennadi Procopciuc 1778a4f840bSGhennadi Procopciuc ret = clk_enable(S32CC_CLK_DDR); 1788a4f840bSGhennadi Procopciuc if (ret != 0) { 1798a4f840bSGhennadi Procopciuc return ret; 1808a4f840bSGhennadi Procopciuc } 1818a4f840bSGhennadi Procopciuc 1828a4f840bSGhennadi Procopciuc return ret; 1838a4f840bSGhennadi Procopciuc } 1848a4f840bSGhennadi Procopciuc 18547b3a825SGhennadi Procopciuc static int enable_usdhc_clk(void) 18647b3a825SGhennadi Procopciuc { 18747b3a825SGhennadi Procopciuc int ret; 18847b3a825SGhennadi Procopciuc 18947b3a825SGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX14, 19047b3a825SGhennadi Procopciuc S32CC_CLK_PERIPH_PLL_DFS3); 19147b3a825SGhennadi Procopciuc if (ret != 0) { 19247b3a825SGhennadi Procopciuc return ret; 19347b3a825SGhennadi Procopciuc } 19447b3a825SGhennadi Procopciuc 19547b3a825SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_DFS3, 19647b3a825SGhennadi Procopciuc S32CC_PERIPH_DFS_PHI3_FREQ, NULL); 19747b3a825SGhennadi Procopciuc if (ret != 0) { 19847b3a825SGhennadi Procopciuc return ret; 19947b3a825SGhennadi Procopciuc } 20047b3a825SGhennadi Procopciuc 20147b3a825SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_USDHC, S32CC_USDHC_FREQ, NULL); 20247b3a825SGhennadi Procopciuc if (ret != 0) { 20347b3a825SGhennadi Procopciuc return ret; 20447b3a825SGhennadi Procopciuc } 20547b3a825SGhennadi Procopciuc 20647b3a825SGhennadi Procopciuc ret = clk_enable(S32CC_CLK_USDHC); 20747b3a825SGhennadi Procopciuc if (ret != 0) { 20847b3a825SGhennadi Procopciuc return ret; 20947b3a825SGhennadi Procopciuc } 21047b3a825SGhennadi Procopciuc 21147b3a825SGhennadi Procopciuc return ret; 21247b3a825SGhennadi Procopciuc } 21347b3a825SGhennadi Procopciuc 21461b5ef21SGhennadi Procopciuc int s32cc_init_core_clocks(void) 215d3869455SGhennadi Procopciuc { 216d3869455SGhennadi Procopciuc int ret; 217d3869455SGhennadi Procopciuc 21861b5ef21SGhennadi Procopciuc ret = s32cc_clk_register_drv(false); 219514c7380SGhennadi Procopciuc if (ret != 0) { 220514c7380SGhennadi Procopciuc return ret; 221514c7380SGhennadi Procopciuc } 222d3869455SGhennadi Procopciuc 2235300040bSGhennadi Procopciuc ret = setup_fxosc(); 224d3869455SGhennadi Procopciuc if (ret != 0) { 225d3869455SGhennadi Procopciuc return ret; 226d3869455SGhennadi Procopciuc } 227d3869455SGhennadi Procopciuc 2285300040bSGhennadi Procopciuc ret = setup_arm_pll(); 2298653352aSGhennadi Procopciuc if (ret != 0) { 2308653352aSGhennadi Procopciuc return ret; 2318653352aSGhennadi Procopciuc } 2328653352aSGhennadi Procopciuc 233d3869455SGhennadi Procopciuc ret = enable_a53_clk(); 234d3869455SGhennadi Procopciuc if (ret != 0) { 235d3869455SGhennadi Procopciuc return ret; 236d3869455SGhennadi Procopciuc } 237d3869455SGhennadi Procopciuc 238b8ad8800SGhennadi Procopciuc ret = enable_xbar_clk(); 239b8ad8800SGhennadi Procopciuc if (ret != 0) { 240b8ad8800SGhennadi Procopciuc return ret; 241b8ad8800SGhennadi Procopciuc } 242b8ad8800SGhennadi Procopciuc 24361b5ef21SGhennadi Procopciuc return ret; 24461b5ef21SGhennadi Procopciuc } 24561b5ef21SGhennadi Procopciuc 24661b5ef21SGhennadi Procopciuc int s32cc_init_early_clks(void) 24761b5ef21SGhennadi Procopciuc { 24861b5ef21SGhennadi Procopciuc int ret; 24961b5ef21SGhennadi Procopciuc 25061b5ef21SGhennadi Procopciuc ret = s32cc_clk_register_drv(true); 25161b5ef21SGhennadi Procopciuc if (ret != 0) { 25261b5ef21SGhennadi Procopciuc return ret; 25361b5ef21SGhennadi Procopciuc } 25461b5ef21SGhennadi Procopciuc 2555300040bSGhennadi Procopciuc ret = setup_periph_pll(); 2565300040bSGhennadi Procopciuc if (ret != 0) { 2575300040bSGhennadi Procopciuc return ret; 2585300040bSGhennadi Procopciuc } 2595300040bSGhennadi Procopciuc 260e4462daeSGhennadi Procopciuc ret = enable_uart_clk(); 261e4462daeSGhennadi Procopciuc if (ret != 0) { 262e4462daeSGhennadi Procopciuc return ret; 263e4462daeSGhennadi Procopciuc } 264e4462daeSGhennadi Procopciuc 26518c2b137SGhennadi Procopciuc ret = setup_ddr_pll(); 26618c2b137SGhennadi Procopciuc if (ret != 0) { 26718c2b137SGhennadi Procopciuc return ret; 26818c2b137SGhennadi Procopciuc } 26918c2b137SGhennadi Procopciuc 2708a4f840bSGhennadi Procopciuc ret = enable_ddr_clk(); 2718a4f840bSGhennadi Procopciuc if (ret != 0) { 2728a4f840bSGhennadi Procopciuc return ret; 2738a4f840bSGhennadi Procopciuc } 2748a4f840bSGhennadi Procopciuc 27547b3a825SGhennadi Procopciuc ret = enable_usdhc_clk(); 27647b3a825SGhennadi Procopciuc if (ret != 0) { 27747b3a825SGhennadi Procopciuc return ret; 27847b3a825SGhennadi Procopciuc } 27947b3a825SGhennadi Procopciuc 280d3869455SGhennadi Procopciuc return ret; 281d3869455SGhennadi Procopciuc } 282