xref: /rk3399_ARM-atf/drivers/nxp/clk/s32cc/s32cc_early_clks.c (revision 61b5ef21af8bcb38d3492e15d1d3d1fbecf3cf49)
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