166af5425SGhennadi Procopciuc /* 266af5425SGhennadi Procopciuc * Copyright 2024 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) 2166af5425SGhennadi Procopciuc 225300040bSGhennadi Procopciuc static int setup_fxosc(void) 2366af5425SGhennadi Procopciuc { 2466af5425SGhennadi Procopciuc int ret; 2566af5425SGhennadi Procopciuc 26d3869455SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL); 27d3869455SGhennadi Procopciuc if (ret != 0) { 28d3869455SGhennadi Procopciuc return ret; 29d3869455SGhennadi Procopciuc } 30d3869455SGhennadi Procopciuc 31d3869455SGhennadi Procopciuc return ret; 32d3869455SGhennadi Procopciuc } 33d3869455SGhennadi Procopciuc 345300040bSGhennadi Procopciuc static int setup_arm_pll(void) 35d3869455SGhennadi Procopciuc { 36d3869455SGhennadi Procopciuc int ret; 3766af5425SGhennadi Procopciuc 3883af4504SGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_ARM_PLL_MUX, S32CC_CLK_FXOSC); 3983af4504SGhennadi Procopciuc if (ret != 0) { 4083af4504SGhennadi Procopciuc return ret; 4183af4504SGhennadi Procopciuc } 4283af4504SGhennadi Procopciuc 437ad4e231SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_ARM_PLL_VCO, S32CC_ARM_PLL_VCO_FREQ, NULL); 447ad4e231SGhennadi Procopciuc if (ret != 0) { 457ad4e231SGhennadi Procopciuc return ret; 467ad4e231SGhennadi Procopciuc } 477ad4e231SGhennadi Procopciuc 48de950ef0SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_ARM_PLL_PHI0, S32CC_ARM_PLL_PHI0_FREQ, NULL); 49de950ef0SGhennadi Procopciuc if (ret != 0) { 50de950ef0SGhennadi Procopciuc return ret; 51de950ef0SGhennadi Procopciuc } 52de950ef0SGhennadi Procopciuc 53b5101c45SGhennadi Procopciuc return ret; 54b5101c45SGhennadi Procopciuc } 55b5101c45SGhennadi Procopciuc 565300040bSGhennadi Procopciuc static int setup_periph_pll(void) 578653352aSGhennadi Procopciuc { 588653352aSGhennadi Procopciuc int ret; 598653352aSGhennadi Procopciuc 608653352aSGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_PERIPH_PLL_MUX, S32CC_CLK_FXOSC); 618653352aSGhennadi Procopciuc if (ret != 0) { 628653352aSGhennadi Procopciuc return ret; 638653352aSGhennadi Procopciuc } 648653352aSGhennadi Procopciuc 658653352aSGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_VCO, S32CC_PERIPH_PLL_VCO_FREQ, NULL); 668653352aSGhennadi Procopciuc if (ret != 0) { 678653352aSGhennadi Procopciuc return ret; 688653352aSGhennadi Procopciuc } 698653352aSGhennadi Procopciuc 708653352aSGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_PHI3, S32CC_PERIPH_PLL_PHI3_FREQ, NULL); 718653352aSGhennadi Procopciuc if (ret != 0) { 728653352aSGhennadi Procopciuc return ret; 738653352aSGhennadi Procopciuc } 748653352aSGhennadi Procopciuc 758653352aSGhennadi Procopciuc return ret; 768653352aSGhennadi Procopciuc } 778653352aSGhennadi Procopciuc 78d3869455SGhennadi Procopciuc static int enable_a53_clk(void) 79d3869455SGhennadi Procopciuc { 80d3869455SGhennadi Procopciuc int ret; 81d3869455SGhennadi Procopciuc 82d3869455SGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_MC_CGM1_MUX0, S32CC_CLK_ARM_PLL_PHI0); 83d3869455SGhennadi Procopciuc if (ret != 0) { 84d3869455SGhennadi Procopciuc return ret; 85d3869455SGhennadi Procopciuc } 86d3869455SGhennadi Procopciuc 87d3869455SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_A53_CORE, S32CC_A53_FREQ, NULL); 88d3869455SGhennadi Procopciuc if (ret != 0) { 89d3869455SGhennadi Procopciuc return ret; 90d3869455SGhennadi Procopciuc } 91d3869455SGhennadi Procopciuc 927004f678SGhennadi Procopciuc ret = clk_enable(S32CC_CLK_A53_CORE); 937004f678SGhennadi Procopciuc if (ret != 0) { 947004f678SGhennadi Procopciuc return ret; 957004f678SGhennadi Procopciuc } 967004f678SGhennadi Procopciuc 9766af5425SGhennadi Procopciuc return ret; 9866af5425SGhennadi Procopciuc } 99d3869455SGhennadi Procopciuc 100b8ad8800SGhennadi Procopciuc static int enable_xbar_clk(void) 101b8ad8800SGhennadi Procopciuc { 102b8ad8800SGhennadi Procopciuc int ret; 103b8ad8800SGhennadi Procopciuc 104b8ad8800SGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX0, S32CC_CLK_ARM_PLL_DFS1); 105b8ad8800SGhennadi Procopciuc if (ret != 0) { 106b8ad8800SGhennadi Procopciuc return ret; 107b8ad8800SGhennadi Procopciuc } 108b8ad8800SGhennadi Procopciuc 109b8ad8800SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_XBAR_2X, S32CC_XBAR_2X_FREQ, NULL); 110b8ad8800SGhennadi Procopciuc if (ret != 0) { 111b8ad8800SGhennadi Procopciuc return ret; 112b8ad8800SGhennadi Procopciuc } 113b8ad8800SGhennadi Procopciuc 114b8ad8800SGhennadi Procopciuc ret = clk_enable(S32CC_CLK_ARM_PLL_DFS1); 115b8ad8800SGhennadi Procopciuc if (ret != 0) { 116b8ad8800SGhennadi Procopciuc return ret; 117b8ad8800SGhennadi Procopciuc } 118b8ad8800SGhennadi Procopciuc 119b8ad8800SGhennadi Procopciuc ret = clk_enable(S32CC_CLK_XBAR_2X); 120b8ad8800SGhennadi Procopciuc if (ret != 0) { 121b8ad8800SGhennadi Procopciuc return ret; 122b8ad8800SGhennadi Procopciuc } 123b8ad8800SGhennadi Procopciuc 124b8ad8800SGhennadi Procopciuc return ret; 125b8ad8800SGhennadi Procopciuc } 126b8ad8800SGhennadi Procopciuc 127e4462daeSGhennadi Procopciuc static int enable_uart_clk(void) 128e4462daeSGhennadi Procopciuc { 129e4462daeSGhennadi Procopciuc int ret; 130e4462daeSGhennadi Procopciuc 131e4462daeSGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX8, S32CC_CLK_PERIPH_PLL_PHI3); 132e4462daeSGhennadi Procopciuc if (ret != 0) { 133e4462daeSGhennadi Procopciuc return ret; 134e4462daeSGhennadi Procopciuc } 135e4462daeSGhennadi Procopciuc 136e4462daeSGhennadi Procopciuc ret = clk_enable(S32CC_CLK_LINFLEX_BAUD); 137e4462daeSGhennadi Procopciuc if (ret != 0) { 138e4462daeSGhennadi Procopciuc return ret; 139e4462daeSGhennadi Procopciuc } 140e4462daeSGhennadi Procopciuc 141e4462daeSGhennadi Procopciuc return ret; 142e4462daeSGhennadi Procopciuc } 143e4462daeSGhennadi Procopciuc 14418c2b137SGhennadi Procopciuc static int setup_ddr_pll(void) 14518c2b137SGhennadi Procopciuc { 14618c2b137SGhennadi Procopciuc int ret; 14718c2b137SGhennadi Procopciuc 14818c2b137SGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_DDR_PLL_MUX, S32CC_CLK_FXOSC); 14918c2b137SGhennadi Procopciuc if (ret != 0) { 15018c2b137SGhennadi Procopciuc return ret; 15118c2b137SGhennadi Procopciuc } 15218c2b137SGhennadi Procopciuc 15318c2b137SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_DDR_PLL_VCO, S32CC_DDR_PLL_VCO_FREQ, NULL); 15418c2b137SGhennadi Procopciuc if (ret != 0) { 15518c2b137SGhennadi Procopciuc return ret; 15618c2b137SGhennadi Procopciuc } 15718c2b137SGhennadi Procopciuc 15818c2b137SGhennadi Procopciuc ret = clk_set_rate(S32CC_CLK_DDR_PLL_PHI0, S32CC_DDR_PLL_PHI0_FREQ, NULL); 15918c2b137SGhennadi Procopciuc if (ret != 0) { 16018c2b137SGhennadi Procopciuc return ret; 16118c2b137SGhennadi Procopciuc } 16218c2b137SGhennadi Procopciuc 16318c2b137SGhennadi Procopciuc return ret; 16418c2b137SGhennadi Procopciuc } 16518c2b137SGhennadi Procopciuc 1668a4f840bSGhennadi Procopciuc static int enable_ddr_clk(void) 1678a4f840bSGhennadi Procopciuc { 1688a4f840bSGhennadi Procopciuc int ret; 1698a4f840bSGhennadi Procopciuc 1708a4f840bSGhennadi Procopciuc ret = clk_set_parent(S32CC_CLK_MC_CGM5_MUX0, S32CC_CLK_DDR_PLL_PHI0); 1718a4f840bSGhennadi Procopciuc if (ret != 0) { 1728a4f840bSGhennadi Procopciuc return ret; 1738a4f840bSGhennadi Procopciuc } 1748a4f840bSGhennadi Procopciuc 1758a4f840bSGhennadi Procopciuc ret = clk_enable(S32CC_CLK_DDR); 1768a4f840bSGhennadi Procopciuc if (ret != 0) { 1778a4f840bSGhennadi Procopciuc return ret; 1788a4f840bSGhennadi Procopciuc } 1798a4f840bSGhennadi Procopciuc 1808a4f840bSGhennadi Procopciuc return ret; 1818a4f840bSGhennadi Procopciuc } 1828a4f840bSGhennadi Procopciuc 183*61b5ef21SGhennadi Procopciuc int s32cc_init_core_clocks(void) 184d3869455SGhennadi Procopciuc { 185d3869455SGhennadi Procopciuc int ret; 186d3869455SGhennadi Procopciuc 187*61b5ef21SGhennadi Procopciuc ret = s32cc_clk_register_drv(false); 188514c7380SGhennadi Procopciuc if (ret != 0) { 189514c7380SGhennadi Procopciuc return ret; 190514c7380SGhennadi Procopciuc } 191d3869455SGhennadi Procopciuc 1925300040bSGhennadi Procopciuc ret = setup_fxosc(); 193d3869455SGhennadi Procopciuc if (ret != 0) { 194d3869455SGhennadi Procopciuc return ret; 195d3869455SGhennadi Procopciuc } 196d3869455SGhennadi Procopciuc 1975300040bSGhennadi Procopciuc ret = setup_arm_pll(); 1988653352aSGhennadi Procopciuc if (ret != 0) { 1998653352aSGhennadi Procopciuc return ret; 2008653352aSGhennadi Procopciuc } 2018653352aSGhennadi Procopciuc 202d3869455SGhennadi Procopciuc ret = enable_a53_clk(); 203d3869455SGhennadi Procopciuc if (ret != 0) { 204d3869455SGhennadi Procopciuc return ret; 205d3869455SGhennadi Procopciuc } 206d3869455SGhennadi Procopciuc 207b8ad8800SGhennadi Procopciuc ret = enable_xbar_clk(); 208b8ad8800SGhennadi Procopciuc if (ret != 0) { 209b8ad8800SGhennadi Procopciuc return ret; 210b8ad8800SGhennadi Procopciuc } 211b8ad8800SGhennadi Procopciuc 212*61b5ef21SGhennadi Procopciuc return ret; 213*61b5ef21SGhennadi Procopciuc } 214*61b5ef21SGhennadi Procopciuc 215*61b5ef21SGhennadi Procopciuc int s32cc_init_early_clks(void) 216*61b5ef21SGhennadi Procopciuc { 217*61b5ef21SGhennadi Procopciuc int ret; 218*61b5ef21SGhennadi Procopciuc 219*61b5ef21SGhennadi Procopciuc ret = s32cc_clk_register_drv(true); 220*61b5ef21SGhennadi Procopciuc if (ret != 0) { 221*61b5ef21SGhennadi Procopciuc return ret; 222*61b5ef21SGhennadi Procopciuc } 223*61b5ef21SGhennadi Procopciuc 2245300040bSGhennadi Procopciuc ret = setup_periph_pll(); 2255300040bSGhennadi Procopciuc if (ret != 0) { 2265300040bSGhennadi Procopciuc return ret; 2275300040bSGhennadi Procopciuc } 2285300040bSGhennadi Procopciuc 229e4462daeSGhennadi Procopciuc ret = enable_uart_clk(); 230e4462daeSGhennadi Procopciuc if (ret != 0) { 231e4462daeSGhennadi Procopciuc return ret; 232e4462daeSGhennadi Procopciuc } 233e4462daeSGhennadi Procopciuc 23418c2b137SGhennadi Procopciuc ret = setup_ddr_pll(); 23518c2b137SGhennadi Procopciuc if (ret != 0) { 23618c2b137SGhennadi Procopciuc return ret; 23718c2b137SGhennadi Procopciuc } 23818c2b137SGhennadi Procopciuc 2398a4f840bSGhennadi Procopciuc ret = enable_ddr_clk(); 2408a4f840bSGhennadi Procopciuc if (ret != 0) { 2418a4f840bSGhennadi Procopciuc return ret; 2428a4f840bSGhennadi Procopciuc } 2438a4f840bSGhennadi Procopciuc 244d3869455SGhennadi Procopciuc return ret; 245d3869455SGhennadi Procopciuc } 246